如何在给定每个维度的大小和维度数量的情况下迭代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
您可以使用递归,为每个维度“猜测”其索引并在较小的问题上递归调用,类似于以下伪代码:
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
是表示当前部分结果的向量使用 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上找到。
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)))
在 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;
}
例子:
您可以使用递归。以下是嵌套数组的伪代码解决方案:
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
以下是我在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
n
维度做什么?我猜你需要知道这个,因此你也知道了维度的数量... - Veger