有没有办法迭代n维数组(其中n是可变的)没有使用递归?我目前正在使用C ++,但我想几乎所有语言都可以使用答案。
编辑:实际上我真正的问题有点不同:我实际上想要枚举数组的索引。简单的2D示例,带有2x2数组:0,0; 0,1; 1,0; 1,1。
答案 0 :(得分:8)
void iterate(const std::vector<int> &dims)
{
std::vector<int> idxs(dims.size());
while (1)
{
// Print
for (int i = 0; i < dims.size(); i++)
{
std::cout << idxs[i] << " ";
}
std::cout << "\n";
// Update
int j;
for (j = 0; j < dims.size(); j++)
{
idxs[j]++;
if (idxs[j] < dims[j]) break;
idxs[j] = 0;
}
if (j == dims.size()) break;
}
}
答案 1 :(得分:4)
是的 - 请记住,C ++(或大多数语言)中的任何多维数组都只是一个线性的内存区域。该语言通过自动将任何外部维度索引乘以该维度的大小/偏移量来帮助您。
因此,您可以通过执行与编写array[x][y][z]
时语言相同的算法来“手动”遍历多维数组 - 但当然,您可以针对任意数量的维度执行此操作。
答案 2 :(得分:1)
是肯定的。
如果数组在内存中是“平坦的”,则可以从array
迭代到array + n^n
。
请注意,具有递归的相同解决方案将适用于循环+堆栈。 (任何递归都可以转换为循环+堆栈)。
编辑:编辑完问题之后:确切地说有m ^ n(假设每个维度具有相同数量的元素m
),简单的枚举将为0,1, ...,(M ^ N)-1。访问是通过array + ENUM_NUMBER
。
答案 3 :(得分:0)
我最近写了这个通用助手来散列T的NxM数组。
template <class T, size_t N, size_t M>
size_t hash(const T (&aa)[N][M])
{
size_t seed = 0;
for (size_t i=0; i<N; i++)
boost::hash_combine(seed, boost::hash_range(aa[i], aa[i]+M));
return seed;
}
您可以使用相同的要点迭代任意数组
template <class T, size_t N, size_t M, class F>
void for_each(const T (&aa)[N][M], F func)
{
size_t seed = 0;
for (size_t i=0; i<N; i++)
for (size_t j=0; j<M; j++)
func(aa[i][j]);
}
template <class T, size_t N, size_t M, size_t L, class F>
void for_each(const T (&aaa)[N][M][L], F func)
{
size_t seed = 0;
for (size_t i=0; i<N; i++)
for (size_t j=0; j<M; j++)
for (size_t k=0; k<L; k++)
func(aa[i][j][k]);
}
像这样使用:
void display(float f) { std::cout << f << std::endl; }
// ...
float fff[1][2][3];
for_each(fff, display);