10

给定维数和每个变量的大小,我如何迭代一个 n 维数组?

int n;
int size[n];

由于维度的数量不固定,我无法为每个维度编写嵌套循环。我需要代码来处理每个维度的数量。

此外,实际数据存储在 n 维数组或包含大行中所有数据的平面数组中并不重要。两者都可以接受。

int data[16][42][14];   // n-dimensional array
int data[16 * 42 * 14]; // flat array containing the same data
4

5 回答 5

7

您可以使用递归,对于每个维度“猜测”它的索引并递归调用一个较小的问题,类似于(伪代码):

iterate(d,n,size,res):
   if (d >= n): //stop clause
       print res
       return
   for each i from 0 to size[d]:
       res.append(i) //append the "guess" for this dimension
       iterate(d+1,n,size,res)
       res.removeLast //clean up environment before next iteration

在哪里:

  • d是当前访问的维度
  • size,n是输入
  • res是表示当前部分结果的向量

调用 with iterate(0,n,size,res),其中res初始化为空列表。


C++ 代码应该是这样的:

void iterate(int d,int n,int size[], int res[]) {
    if (d >= n) { //stop clause
       print(res,n);
       return;
   }
   for (int i = 0; i < size[d]; i++) { 
       res[d] = i;
       iterate(d+1,n,size,res);
   }
}

完整的代码和一个简单的例子可以在ideone上找到

于 2012-12-26T12:00:16.670 回答
5

Python代码:

def nd_range(start, stop, dims):
  if not dims:
    yield ()
    return
  for outer in nd_range(start, stop, dims - 1):
    for inner in range(start, stop):
      yield outer + (inner,)

例子:

print(list(nd_range(0, 3, 3)))

[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 1, 0), (0, 1, 1), (0, 1, 2), ( 0, 2, 0), (0, 2, 1), (0, 2, 2), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 2, 0), (1, 2, 1), (1, 2, 2), (2, 0, 0), (2, 0, 1), (2, 0, 2), (2, 1, 0), (2, 1, 1), (2, 1, 2), (2, 2, 0) , (2, 2, 1), (2, 2, 2)]

于 2016-11-30T23:18:19.273 回答
1

你可以使用递归。这是嵌套数组的伪代码解决方案:

iterate_n(array, n)
    if n == 0
        do something with the element
    else
        for ary in array
            iterate_n(ary, n-1)
        end_for
    end_if
end
于 2012-12-26T12:07:56.350 回答
0

这是我在 MATLAB 中使用递归的方法:

function out=iterate(data,func,dim)
% Usage: out=iterate(data,func)
% This function individually applies the user defined function 'func' to 
% every element of the array 'data'.
% The third input 'dim' is for internal recursive use only, after global 
% setup variables have been initialized.


global sz inds g_out
% 'sz' is size(data) with singleton dimensions removed
% 'inds' is an array of size [1 length(sz)] containing the current indices
% 'g_out' is where parts of the output are accumulated throughout iteration

if nargin<3
    %Setup 'inds' 'sz' 'g_out'
    dim=1;  %'dim' is the current dimension to iterate through
    sz=size(data);
    if sz(2)==1
        sz=sz(1);
    end
    inds=ones(1,length(sz));

    %Initialize the output as the proper class
    %Depends on the output of the user given function
    switch class(func(data(1)))
        case 'logical'
            g_out= false(sz);
        case 'double'
            g_out=double(zeros(sz));
        case 'char'
            g_out=repmat(' ',sz);
        otherwise
            g_out=cast(zeros(sz),class(func(data(1)))); %#ok<ZEROLIKE>
    end
end

for i=1:sz(dim)
    inds(dim)=i;
    ndx=subs2ind(sz,inds);
    if dim<length(sz)
        iterate(data,func,dim+1);
    else
        g_out(ndx)=func(data(ndx));
    end
end
out=g_out;
end
于 2016-11-30T22:46:44.420 回答
0

要在 JavaScript 中列出所有组合,无需递归:

function listCoords(dimensions) {
    var cumulatives = new Array(dimensions.length);
    var total = 1;
    for (var d = dimensions.length - 1; d >= 0; d--) {
        cumulatives[d] = total;
        total *= dimensions[d];
    }
    var coords = new Array(total);
    for (var i = 0; i < total; i++) {
        var coord = new Array(dimensions.length);
        for (var d = dimensions.length - 1; d >= 0; d--) {
            coord[d] = Math.floor(i / cumulatives[d]) % dimensions[d];
        }
        coords[i] = coord;
    }
    return coords;
}

例子:

  • [2, 3] 返回 [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2]]
  • [3, 2] 返回 [[0,0],[0,1],[1,0],[1,1],[2,0],[2,1]]
  • [2, 2, 2] 返回 [[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[ 1,0,1],[1,1,0],[1,1,1]]
于 2022-02-01T14:09:41.580 回答