0

array[i % n, i / n]when i=0 < n*m for an,m arrayを使用して、2D 配列のすべての要素をトラバースする方法を知っています。2D 配列の境界要素のみをトラバースする便利な式はありますか?

たとえば、2D の場合、与えられた行列

ここに画像の説明を入力

'a' のみがトラバースされます。3Dで説明できたらいいのにと思いますが、これで解決することを願っています

4

2 に答える 2

0

これは私が 2D 用に思いついたものです: (これは Java ですが、C# に変換するには、System.out.printandMath.ceilを C# の同等のものに置き換えるだけで済みます)

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

ライブデモ

ご覧のとおり、問題がなければ 4 つのコーナー セルが繰り返されます。

それぞれがどのように見えるか見てみましょうxi( Math.ceiland/(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.ceiland/(1.0*m)またはは、andを 1/(1.0*n)に変更するためのものです (これは、適用可能な制限 (または) が他の制限 (または)より大きい場合に発生します)。x3y3mnnm

上記の表を使用して、コード内のステートメントにthe limit-1見られるように、最初の値を 2 番目と 3 番目の値で乗算し、その積を加算することによって、目的のトラバーサルを取得できます。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
于 2013-10-17T12:56:19.177 に答える
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

2 番目のインデックスの場合: グラフは次のとおりです。

        _______
       /       \
      /         \
 ____/           \
 0   n n+m  2n+m 2n+2m

i を使用して同様の式を作成できます。

于 2013-10-17T11:13:52.117 に答える