如何迭代n维?

时间:2012-12-26 11:57:20

标签: arrays algorithm loops dimension

如果给定维度的数量和每个变量的大小,我如何迭代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 个答案:

答案 0 :(得分: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)]

答案 1 :(得分:4)

你可以使用递归,为每个维度“猜测”它的索引并递归地调用一个较小的问题,这与(peudo代码)一致:

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是当前访问的维度
  • sizen是输入
  • res是表示当前部分结果的向量

使用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

上提供的简单示例

答案 2 :(得分:0)

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

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

答案 3 :(得分: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