假设我有一个以行主顺序存储的4x3线性整数数组。布局(索引)如下所示。假设每个索引的值与索引相同。
00 01 02 03
04 05 06 07
08 09 10 11
我可以循环遍历这个数组:
for(int y = 0; y < 3; ++y)
for(int x = 0; x < 4; ++x)
std::cout << array[y*4+x] << ",";
我会得到
00,01,02,03,04,05,06,07,08,09,10,11,
当然,我可以采用稍微不同的方式循环:
for(int x = 0; x < 4; ++x)
for(int y = 0; y < 3; ++y)
std::cout << array[y*4+x] << ",";
得到
00,04,08,01,05,09,02,06,10,03,07,11,
但是有没有办法在没有首先对数组进行排序的情况下循环获取以下(或类似)结果:
05,04,01,06,09,00,02,10,08,07,03,11
也就是说,从某个指定位置[x=1,y=1]
开始,然后向外迭代(一种)螺旋,按距离排序。
05 02 06 10
01 00 03 09
08 04 07 11
我知道我可以通过首先通过一些谓词对数组进行排序来实现这一点,该谓词返回[x=1,y=1]
的距离,但是(对于性能)是否可以不先进行排序?
修改
详细说明一下,我只想从点[x=1,y=1]
开始并迭代,好像这些点已经通过Manhatten(|x1-x2| + |y1-y2|
)甚至Euclidean(sqrt((x1-x2)^2 + (y1-y2)^2)
)进行了排序。
这是一个更大的数组。它不一定非常像这样,因为它可以满足排序,具有不同的输出(例如,它可以是CCW而不是CW)。
05 01 06 11 17
04 00 02 09 15
08 03 07 14 18
13 10 12 16 19
答案 0 :(得分:2)
以正确的顺序为螺旋制作一系列偏移,足够长的任何起始位置。无论是作为静态表还是作为生成函数。
循环遍历该偏移序列,将每个序列添加到起始坐标。跳过任何超出界限的坐标。找到width * height
有效坐标后停止
答案 1 :(得分:1)
对于曼哈顿距离,您可能会使用以下内容:
visit(center);
for (int distance = 1; distance != max_distance; ++distance) {
for (int i = 0; i != distance; ++i) {
visit(center - {-distance + i, i});
}
for (int i = 0; i != distance; ++i) {
visit(center - {i, distance - i});
}
for (int i = 0; i != distance; ++i) {
visit(center - {distance - i, -i});
}
for (int i = 0; i != distance; ++i) {
visit(center - {-i, -distance + i});
}
}
您可以在visit
中添加绑定检查,或调整每个边界(您必须拆分每个内部循环)。