C++ 从卷或区域中的起点向外迭代,而不进行排序

C++ 从卷或区域中的起点向外迭代,而不进行排序,c++,loops,graph-algorithm,C++,Loops,Graph Algorithm,假设我有一个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] << ","; 当然,我可以用稍微不同的方式循环: for(int x = 0

假设我有一个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] << ",";
当然,我可以用稍微不同的方式循环:

for(int x = 0; x < 4; ++x)
   for(int y = 0; y < 3; ++y)
       std::cout << array[y*4+x] << ",";
但是,有没有一种方法,在不首先对数组排序的情况下,通过它循环得到以下(或类似)结果:

也就是说,从某个指定的位置开始
[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 |
)甚至欧几里德(
sqrt((x1-x2)^2+(y1-y2)^2)
)排序的

这是一个更大的数组。它不必完全像这样,因为它可以满足排序,并具有不同的输出(例如,它可以是CCW而不是CW)


按照螺旋线的正确顺序制作一系列偏移,其长度足以容纳任何起始位置。要么作为静态表,要么作为生成函数


循环通过该偏移序列,将每个偏移添加到起始坐标。跳过任何越界坐标。当您找到有效的坐标时停止,按照正确的螺旋顺序进行偏移序列,足够长,适合任何起始位置。要么作为静态表,要么作为生成函数


循环通过该偏移序列,将每个偏移添加到起始坐标。跳过任何越界坐标。当您找到曼哈顿距离的有效坐标时停止,您可以使用如下方法:

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(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});
    }
}

您可以添加绑定签入
vision
,或者调整每个边界(您必须拆分每个内部循环)。

请提供一个更大的数组来解释此螺旋如何工作。但对你的问题最简洁的回答是“是的”;计算出给定步骤中要访问的数组中的x和y的方程;然后从那里开始。请提供一个更大的数组来解释这个螺旋是如何工作的。但对你的问题最简洁的回答是“是的”;计算出给定步骤中要访问的数组中的x和y的方程;然后从那里开始。
05 02 06 10
01 00 03 09
08 04 07 11
05 01 06 11 17
04 00 02 09 15
08 03 07 14 18
13 10 12 16 19
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});
    }
}