我知道如何遍历二维数组的每个元素,使用array[i % n, i / n]
when i=0 < n*m for an,m 数组。是否有一个方便的公式可以仅遍历二维数组的边界元素?
例如,对于 2D,给定一个矩阵
只有“a”被遍历。希望我可以为 3d 说明,但希望这可以清除它
假设顺时针或逆时针遍历,对于第一个索引,可能类似于:
for n = 5, m = 3.
0 1 2 3 4
11 5
10 9 8 7 6
For i = 0 to 2m + 2n - 5
[ max( i - max( i - (n-1), 0) - max( i - (m+n-2), 0 ), 0) ]
column index first increase from 0 to n-1
Then it stays constant at n-1 upto i = n+m-2
Then it decreases along with i to 0 upto i = 2n + m - 3
Then again it stays constant at 0 upto 2n + 2m - 5.
图表是:
n-1_________
/ \
/ \
/ \__________
0 n-1 n+m-2 2n+m-3 2n+2m-5
对于第二个索引:图表是:
_______
/ \
/ \
____/ \
0 n n+m 2n+m 2n+2m
您可以使用 i 形成类似的表达式。
这就是我为 2D 想出的:(它是 Java,但要转换为 C#,你应该只需要用 C# 等价物替换System.out.print
和)Math.ceil
int n = 5, m = 3;
for (int i = 0; i < 2*(m+n); i++)
{
int x1 = i/(m+2*n),
x2 = (i%(m+n))%n,
x3 = (int)Math.ceil(((m+i)%(m+n)) / m / (1.0*n));
System.out.print(x1*(n-1) + x2 * x3 + " ");
int y1 = i/(m+n) - i/(m+2*n),
y2 = x2,
y3 = (int)Math.ceil((i%(m+n)) / n / (1.0*m));
System.out.println(y1*(m-1) + y2 * y3);
}
如果您愿意,上面当然可以写成访问数组的单个语句。
请注意,由于(i%(m+n))%n
,这仅适用于n > m
。最简单的解决方法可能是将其粘贴到一个接受 4 个参数的函数中,x,y,m,n
根据是否更大,可以轻松地交换这些m
参数n
。
输出:
0 0
1 0
2 0
3 0
4 0
0 0
0 1
0 2
0 2
1 2
2 2
3 2
4 2
4 0
4 1
4 2
现场演示。
如您所见,如果可以的话,它确实会重复 4 个角单元格。
让我们看看每个xi
看起来像什么(没有Math.ceil
and /(1.0*m)
or /(1.0*n)
):
i x1 x2 x3 y1 y2 y3
0 0 0 1 0 0 0
1 0 1 1 0 1 0
2 0 2 1 0 2 0
3 0 3 2 0 3 0
4 0 4 2 0 4 0
5 0 0 0 0 0 1
6 0 1 0 0 1 1
7 0 2 0 0 2 1
8 0 0 1 1 0 0
9 0 1 1 1 1 0
10 0 2 1 1 2 0
11 0 3 2 1 3 0
12 0 4 2 1 4 0
13 1 0 0 0 0 1
14 1 1 0 0 1 1
15 1 2 0 0 2 1
Math.ceil
和/(1.0*m)
or/(1.0*n)
只是在它们 > 1 的地方将 and 更改为 1(如果适用的限制 ( or x3
)大于另一个限制 ( or ),则会发生这种情况。y3
m
n
n
m
然后可以使用上表通过将第一个乘以the limit-1
并添加第二个和第三个的乘积来获得所需的遍历,如print
代码中的语句所示。
弄清楚上面的表格会有用,如何生成它以及如何使用它只是玩了一下的问题。
是的,我没有为 3D 解决这个问题。
如您所见,稍长一些的内容更具可读性:
int n = 5, m = 3;
int x = 0, y = 0;
int xInc = 1, yInc = 0;
while (true)
{
System.out.println(x + " " + y);
// got to right, go down
if (x == n-1 && xInc == 1)
{
xInc = 0;
yInc = 1;
}
// got to bottom, go left
else if (y == m-1 && yInc == 1)
{
xInc = -1;
yInc = 0;
}
// got to left, go up
else if (x == 0 && xInc == -1)
{
xInc = 0;
yInc = -1;
}
// got to top, stop
else if (y == 0 && yInc == -1)
{
break;
}
x += xInc;
y += yInc;
}
输出:
0 0
1 0
2 0
3 0
4 0
4 1
4 2
3 2
2 2
1 2
0 2
0 1
0 0