簡體   English   中英

C++:以對角線方式處理二維數組元素

[英]C++: Process 2d array elements in a diagonal fashion

假設我們有一個二維 arrays, arr[N][N] ,其中N是一個constant integer 假設arr的每個元素都被初始化。

如何使用嵌套的 for 循環打印arr antidiagonal-wise 的元素?

我的意思是:

  • 在最外層循環的第一次迭代之后,將打印arr[0][0]
  • 在最外層循環的第二次迭代之后,將打印arr[0][1]arr[1][0]
  • 在最外層循環的第三次迭代之后,將打印arr[0][2]arr[1][1]arr[2][0]
  • ...
  • 在最外層循環的最后一次迭代之后,將打印arr[N-1][N-1]

謝謝你的時間!

對不起所有寫“下半場應該相似”的人......不是。

無論如何,這里是 go:

// traverse array diagonally
int c, tmp, x;
for (c = N - 1; c > -N; c--) {
    tmp = N - abs(c) - 1;
    x = tmp;
    while (x >= 0) {
        if (c >= 0) {
            std::cout << arr[x][tmp - x] << ", ";
        }
        else {
            std::cout << arr[N - (tmp - x) - 1][(N-1)-x] << ", ";
        }
        --x;
    }
    std::cout << "\n";
}

你需要這個來玩游戲還是什么?

[編輯] 再看一遍,我認為我的答案寫得不是很好。 這是一個快速瀏覽:

假設 N 為 3。

我們需要的是對坐標組合的迭代,如下所示:

(0, 0)
(1, 0), (0, 1)
(2, 0), (1, 1), (0, 2)
(2, 1), (1, 2)
(2, 2)

所以首先是一些占位符:

int c,    // a counter, set by the outer loop
    tmp,  // for intermediate results
    x;    // the x-index into *arr* (*y* will be defined implicitly)

現在這個外循環

for (c = N - 1; c > -N; c--) { 

使c迭代{2, 1, 0, -1, 2}

下一步

    tmp = N - abs(c) - 1;
    x = tmp;

{2, 1, 0, -1, -2}轉換為{0, 1, 2, 1, 0} ,這是此步驟所需輸出的長度減一(因此它們可以用作索引)。 我們制作了兩個副本, tmpx

現在我們從x倒數到0

    while (x >= 0) {
        ...
        --x;
    }

如果我們在arr的左上半部分,由c >= 0表示,則arr的 x 索引需要從對角線開始,並且 go 下降到零(0 到 0、1 到 0 和 2 到 0) ,而 y 索引需要從零開始,並且 go 直到對角線(0 到 0、0 到 1 和 0 到 2)

        if (c >= 0) {
            std::cout << arr[x][tmp - x] << ", ";
        }

一旦我們在右下半部分,x 索引需要從N開始並向下到對角線(2 到 1 和 2 到 2) ,而 y 索引需要從對角線開始並且 go 向上到N(1 到 2 和 2 到 2)

        else {
            std::cout << arr[N - (tmp - x) - 1][(N-1)-x] << ", ";
        }

最后,我們只需要在每行末尾換行:

    std::cout << "\n";

薩維? :-)

這將適用於一半的矩陣.. 另一半將是相似的:

for (j = 0 ; j < N ; j++)
{
   for (i = 0 ; i <= j ; i ++)
   {
      printf("%d \n",a[i,j-i]);
   }
}

您可以注意到,對於任何對角線,2 個“相鄰”元素由[x][y][x+1][y-1]給出:也就是說,您向右和向上采取對角線步驟。

所以你可以有一個循環來設置對角線的第一個單元格。 您只需要遍歷y的所有值,從[0][y]開始,然后執行此右上步驟(對角線),直到碰到頂部或右側。 然后你需要做同樣的事情,從[0][N-1]移動到[N-1][N-1]以覆蓋下半場。

代碼如下:

for (int _y = 0; _y < N; _y++) {
    int x = 0, y = _y;
    while (x < N && y >= 0) {
        cout << arr[x][y];
        x++; y--;
    }

    cout << endl; // don't forget a newline
}

我將省略代碼的后半部分,因為它應該大致相同。

這是矩陣兩半的解決方案:

    //First half (including middle diagonal)
    for (int i = 0; i < n; i++) {
        for (int j = 0; j <= i; j++) {
            print array[j][i - j];
        }
        newline;
    }

    //Second half (excluding middle diagonal)
    for (int i = n - 1; i >= 0; i--) {
        for (int j = 0; j < i; j++) {
            print array[n - i + j][n - j - 1];
        }
        newline;
    }

這是 java 代碼片段,但算法相同

for(int i = 0; i < 10; i++){
    for(int j = 0; j <= i; j++){
        System.out.print(a[j][i-j] + " ");
    }
    System.out.println();
}

看起來像這樣:

for(row = 0; row < N; row++){  
   for(j = 0; j <= row; j++){  
      print Array[row - j][j];  
   }  
   newline;  
}  

這是一種我認為有用的解決方案 R 是總行數。

    void diagonalOrder(int arr[][COLS],int R)
    {

        for (int i = 0; i < R+COLS-1; i++)
        {
            int col;
            int row;
            i<COLS?col=i:col=(COLS-1);
            col>i?row=col-i:row=i-col;

            for(int j=col;j>=0 ;j--)
            {
                if(row<R)
                    cout<<arr[row][j]<<" ";
                row++;
            }
            cout<<endl;
        }
    }

ie.
const int ROWS = 4;
const int COLS = 3;

int arr[][COLS] = {{ 1, 2, 4 },
                        { 3, 5, 7},
                        { 6, 8, 10},
                        { 9, 11, 12}
                    };
    diagonalOrder(arr,ROWS);

Output
----------
1
2 3
4 5 6
7 8 9
10 11
12

------------------------------------------------------
const int ROWS = 8;
const int COLS = 3;

    int arr8[][COLS] = {{ 1, 2, 4 },
                        { 3, 5, 7 },
                        { 6, 8, 10 },
                        { 9, 11, 13 },
                        { 12, 14, 16},
                        { 15 ,17, 19},
                        { 18 ,20, 22},
                        { 21, 23, 24}

                    };

    cout<<"\n\n8*3 Matrix"<<endl<<endl;
    diagonalOrder(arr8,8);

--------------------------------------------------------------
Output
--------------------------------------------------------------
1
2 3
4 5 6
7 8 9
10 11 12
13 14 15
16 17 18
19 20 21
22 23
24
-----------------------------------------

    int arr[][COLS] = {{ 1, 2, 4 ,20},
                        { 3, 5, 7,20},
                        { 6, 8, 10,20},
                        { 9, 11, 12,20}
                    };
-------------------------------------------------------------
Output
-------------------------------------------------------------

1
2 3
4 5 6
20 7 8 9
20 10 11
20 12
20


You can work with n*n Matrix ..

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM