仅在其边界上遍历2D或3D阵列/矩阵

时间:2013-10-17 10:21:33

标签: c# arrays algorithm matrix traversal

我知道如何在i = 0< 0时使用array[i % n, i / n]遍历2D数组的每个元素。 n * m表示n,m数组。是否有一个方便的公式来遍历2D数组的边界元素?

例如,对于2D,给定矩阵

enter image description here

仅遍历'a'。希望我可以用3D来说明,但希望这可以解决它

2 个答案:

答案 0 :(得分:0)

假设顺时针或逆时针遍历,可能类似于第一个索引:

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。

形成类似的表达

答案 1 :(得分:0)

这就是我为2D提出的:(它是Java,但要转换为C#,您只需要用C#等价物替换System.out.printMath.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的函数中,根据mn是否更大,可以轻松交换这些参数。

输出:

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

Live demo

正如你所看到的,如果可以的话,它会重复4个角单元格。

让我们看看每个xi的外观(没有Math.ceil/(1.0*m)/(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)/(1.0*n)可以将x3y3更改为1,其中&gt; 1(如果适用的限制(mn)大于其他限制(nm),则会发生这种情况。

然后可以使用上面的表格通过将第一个与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