分配不带递归的多维数组
Allocate a multidimensional array without recursion
>假设我有一个任意大小的整数值数组,该数组指定要分配的数组的每个维度(级别)的元素数,如何在不诉诸递归的情况下分配数组?最好在没有递归的情况下执行此操作,以避免堆栈溢出。
因此,例如,如何完成这样的函数:
template <typename Type>
void* allocMulti (int numDim, int* numElementsPerDim)
{
// 'Type' if one-dimensional, should be 'void*' otherwise
void* multiArray = new Type[numElementsPerDim[0]];
// ...
return multiArray;
}
我正在寻找一种通用算法,该算法可以涵盖没有直接内存访问的语言。
如果数组实际上是一个矩阵(例如长度 AxB 而不是不同长度的数组列表),那么您可以分配长度为 A*B 的单个数组,而不是长度为 A 的数组,其中每个位置都是指向长度为 B 的数组的指针。
这也可以提高性能,因为内存是连续的(较少的分页)。
不过,您必须使用 a[y * B + x] 而不是 a[y][x] 访问每个单元格(假设 dim(a,0) = A 和 dim(a,1) = B。
我的C++有点生疏,但是,我相信这种方法可能会奏效:
T* AllocateMatrix(int dims, int[] dimLengths)
{
// Assert dims >= 1
int length = dims[0];
for (int d = 1; d < dims; d++)
length *= dims[d];
return new T[length];
}
*T AccessMatrix(T* matrix, int dims, int[] dimLengths, int[] pos)
{
// Assert dims >= 1
int p = pos[0];
for (int d = 1; d < dims; d++)
{
p = p * dimLengths[d] + pos[d];
}
return &matrix[p];
}
这是一种方法:将数据值分配为块,然后将(int *)
的所有行分配为块,然后将(int **)
行分配为块,依此类推。
a) 将所有数据值分配为一个块。如果在数组elementsPerDim
中有nDim
维度,则有prod = product(elementsPerDim, nDim)
数据值(您可以轻松计算),因此您需要分配:
int prod = product(elementsPerDim, nDim);
int * intblock = calloc(prod, sizeof(int));
b) 分配所有(int*)
。它们的数量等于除最后一个维度之外的所有维度的乘积,因此您可以简单地调用长度为 nDim-1
的 product()
函数。所以有product(elementsPerDim, nDim-1)
这样的值,每个值的大小sizeof (int*)
.让我们分配它们:
int npointers = product(elementsPerDim, nDim-1);
int ** ptrblock = calloc(npointers, sizeof (int *));
现在,您必须初始化它们以指向上一步中的块。每个指针都得到一个不重叠的 elementsPerDim[nDim-2]
整数块,如下所示:
int rowlength = elementsPerDim[nDim-2];
for (int i=0; i < npointers; i++)
ptrblock[i] = & intblock[i * rowlength]; /* a.k.a. intblock + i*rowlength */
c) 向后迭代步骤 b,直到用完尺寸。即,通过此循环跟进步骤(b):
void ** prev_block = (void **) ptrblock;
void ** curblock;
for (int d = nDim-2; d > 0; d--) {
int npointers = product(elementsPerDim, d);
curblock = calloc(npointers, sizeof (void **));
int rowlength = elementsPerDim[d-1];
for (int i=0; i < npointers; i++)
curblock[i] = & prev_block[i * rowlength];
prev_block = curblock; /* get ready for the next round */
}
完成后,curblock
将是一个指向二级指针块的指针数组,依此类推,指向整数块。您可以使用普通数组表示法来取消引用它们: ptrblock[3][2][15]
等。
我可能在某个地方得到了一个索引,但这应该是算法。您会注意到这是在 C 中,并且使用 void **
而不是堆叠取消引用的数量。你确实说过你对算法感兴趣,而不是对高尔夫类型感兴趣......(只要计算机上的所有指针具有相同的大小,它就应该可以工作。
- 使用递归的数组的最小值.这是怎么回事
- 数组元素打印的递归方法
- 使用递归模板动态分配的多维数组
- 有没有办法使用递归函数找到数组中最小值的 INDEX?C++
- 这种用于查找连续子数组中最大和的递归算法有什么优势吗?
- 使用递归输出数组
- 使用递归反转和打印出数组的内容
- 递归二进制搜索与字符串数组
- 将数组传递给递归函数,同时C++修改它
- 使用递归的序列到达数组末尾的最小跳转次数
- 这是定义一组递归规则的正确方法吗?
- 斐波那契数的递归函数
- 尝试递归获取数组元素的总和
- 在C++中对二维数组进行归零.循环需要2个吗
- C++排序数组递归
- 当我的编译器不符合标准时,如何将数组成员归零
- 数独递归,接受零为合法
- 通过除数组递归地计算和
- 动态数组递归与不同的编译器
- 不使用循环和数和的数字根递归