看似很简单的C/C++问题,google,baidu牛人竟然无人会
编写一个程序:void f(int dim, int *s, int *array)
输入为 : int dim //代表整数型数组的维数,比如dim=5,就是5维数组
int *s //代表对应维的长度。比如 dim=5 的5维数组 int a[3][2][4][5][1]; 则s[0]=3,s[1]=2,s[2]=4,s[3]=5,s[4]=1
输出为 :int *array //生成对应维数的数组array[ s[1] ][ s[2] ]...[ s[dim-1] ],并且初始化为
array[i][j]...[k] = i*j*...*k;
(array是 int * 指针,不是 int **...* 指针)
[解决办法]
说在前:这个是相当于用长度为N的二维数组的数值
来初始化一个N维数组的某一个点的值而已,题目要求我理解是这样
说说想法吧
1 参数检查 (指针不为空,s数组的长度要大于dim)
2 根据dim的值,在堆上new出一个对应dim维数的数组,假设数组名为DIM;
每一维的长度为数组s的长度 (这个是一个很大的开销)
for( dim > 0; dim --) //循环分配
malloc;
3 根据s数组中的数组值,找到对应dim维数组DIM确定点
然后给这个点赋值假设为:
DIM[i][j]...[k] = i*j*...*k;
4 取dim确定点的值,把地址赋值给 array
*array = DIM[i][j]...[k];
5 同第二步 循环释放堆内存(free);
6 最后其实就是通过dim的大小来取s数组中的前dim个值相乘赋值给array
[解决办法]
没多大难度
#include <stdio.h>
#include <string.h>
void* mallocArr(int ncol, int* psize)
{
int res = 1;
for(int i=0; i<ncol; ++i)
res *= psize[i];
int* p = malloc(res*sizeof(int));//数组大小
int* pt = malloc(ncol * sizeof(int));//初始化数组
for(int i=0; i<res; ++i)
{
p[i] = 1;
int t = i;
for(int j=0; j<ncol; ++j)
{
p[i] *= t%psize[ncol-1-j];
t /= psize[ncol-1-j];
}
}
free(pt);
return p; //返回完事
}
int main(int argc, char *argv[])
{
int size[5] = {2, 2, 3, 4, 5};
int* pres = mallocArr(5, size);
for(int i=0; i<2*2*3*4*5; ++i)
printf("%d\t", pres[i]);
free(pres);
return 0;
}
[解决办法]
丑陋就丑陋了,谁叫他把参数搞成那样,注意*(int**)array这样不安全,应*(int**)(void*)array。
[解决办法]
感觉接口应该是
void f(int dim, int *s, int **array)
然后
int dim = 5;
int s[5] = { 3, 2, 4, 5, 1, };
int * p = NULL;
f(dim, s, &p);
void f(int dim, int * s, int ** array)
{
size_t size = 1;
for (int i = 0; i < dim; i++)
size *= s[i];
*array = (int *)malloc(sizeof(int) * size);
int * index = (int *)malloc(sizeof(int) * dim);
for (int i = 0; i < size; i++)
{
size_t cap = size;
int ii = i;
for (int j = 0; j < dim; j++)
{
cap /= s[j];
index[j] = ii / cap;
ii %= cap;
}
int init = 1;
for (int j = 0; j < dim; j++)
init *= index[j];
(*array)[i] = init;
}
free(index);
}
[解决办法]
汗。。丢脸丢大了。。。。。。MallocMem函数可以不要
void InnerFun(int dim, int* s, int** array, int value)
{
*array = new int[*s];
if (dim>1)
{
for (int i=0; i<*s; i++)
InnerFun(dim-1, s+1, (int**)&(*array)[i], value*(i+1));
}
else
{
for (int i=0; i<*s; i++)
(*array)[i] = value*(i+1);
}
}
void f(int dim, int* s, int** array)
{
InnerFun(dim, s, array, 1);
}
void free(int dim, int* s, int* array)
{
if (dim>1)
{
for (int i=0; i<*s; i++)
free(dim-1, s+1, (int*)array[i]);
}
delete []array;
}
void print(int dim, int* s, int* array)
{
if (dim>1)
{
for (int i=0; i<*s; i++)
print(dim-1, s+1, (int*)array[i]);
}
else
{
for (int i=0; i<*s; i++)
printf("%d\n", array[i]);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int dim[] = {3,2,4,5,1};
int *array;
//生成
f(5, dim, &array);
//打印
print(5, dim, array);
//释放
free(5, dim, array);
return 0;
}
[解决办法]
void f(int dim, int *s, int *array)
{
int iloop = 0;
int len = 1;
for(iloop = 0; iloop < dim; ++iloop)
len *= s[iloop];
//如果内存在这里分配的话,分配的指针的值是传不出去的
//所以内存应该是在外部分配的,分配的内存大小为len*sizeof(int)
array = (int*)malloc(len*sizeof(int));
for(iloop = 0; iloop < len; ++iloop)
array[iloop] = calnode(dim, int*s, iloop);
return;
}
int calnode(int dim, int *s, int index)
{
int sum = 1;
int iloop = 0;
int ret = 1;
for(iloop = 0; iloop < dim; ++iloop)
sum *= s[iloop];
for(iloop = dim-1; iloop >= 0; --iloop)
{
sum /= s[iloop];
ret *= iloop % sum;
iloop -= iloop % sum;
}
return ret;
}
[解决办法]
#include <iostream>
using namespace std;
void f(int dim, int *s, int *array)
{
if(array == NULL)
return;
int *ss = new int[dim];
int length=1,tmp;
for(int i=dim-1;i>=0;i--)
{
ss[i] = length;
length*=s[i];
}
for(int i=0;i<length;i++)
{
array[i] = 1;
tmp = i;
for(int j=0;j<dim;j++)
{
array[i]*= tmp / ss[j];
tmp %= ss[j];
}
}
delete [] ss;
}
int main()
{
int *array = new int[3*2*4*5*2];
int s[5] = {3,2,4,5,2};
f(5,s,array);
delete [] array;
return 0;
}
主要是看所谓的n维,在线程内存中怎么存放了,可以简单的这么考虑:
如int s[5] = {3,2,4,5,2},那么从右往左看,是有5个2长度的内存,然后有4个5*2长度的内存,
2个4*5*2的内存,3个2*4*5*2的内存,理解了这种方式,自然迎刃而解。