C ++: обработка 2d элементов массива по диагонали - PullRequest
4 голосов
/ 27 мая 2011

Скажем, у нас есть двумерные массивы, arr[N][N], где N - это constant integer.Предположим, что каждый элемент arr инициализирован.

Как распечатать элементы arr антидиагонально, используя вложенные циклы for?

Что я имею в виду:

  • После первой итерации самого внешнего цикла будет напечатано arr[0][0]
  • После второй итерации самого внешнего цикла будут напечатаны arr[0][1] и arr[1][0]
  • После третьей итерации самого внешнего цикла будут напечатаны arr[0][2], arr[1][1] и arr[2][0]
  • ...
  • После последней итерации внешнегобудет напечатан arr[N-1][N-1].

Спасибо за ваше время!

Ответы [ 7 ]

3 голосов
/ 01 июня 2011

Извините всех, кто написал "Вторая половина должна быть похожа" ... это не так.

В любом случае, вот, пожалуйста:

// 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} , которые являются длинами необходимых выходов на этом шаге минус один (поэтому они могут использоваться в качестве индексов).Мы делаем две копии этого, tmp и x .

Теперь мы отсчитываем от x до 0 :

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

, если мы находимся в верхней левой половине обр. , обозначается c> = 0 , x-индексы в обр. нужно начинать с диагонали и опускаться до нуля (от 0 до 0, от 1 до 0 и от 2 до 0) , тогда как y-индексы должны начинаться с нуля и подниматься до диагонали (от 0 до 0, от 0 до 1 и от 0 до 2) :

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

как только мы окажемся в нижней правой половине, x-индексы должны начинаться с N и до диагонали (от 2 до 1 и от 2 до 2) , тогда как y-индексы должны начинаться с диагонали и доходить до N (от 1 до 2)и 2 к 2) :

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

наконец, нам просто нужен разрыв строки в конце каждой строки:

    std::cout << "\n";

Savy?: -)

2 голосов
/ 27 мая 2011

Вы можете заметить, что для любой диагонали 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
}

Я собираюсь пропустить вторую половину кода, потому что она должна быть примерно такой же.

2 голосов
/ 27 мая 2011

Это будет работать для половины матрицы .. другая половина будет похожа:

for (j = 0 ; j < N ; j++)
{
   for (i = 0 ; i <= j ; i ++)
   {
      printf("%d \n",a[i,j-i]);
   }
}
1 голос
/ 14 мая 2013

Вот решение для обеих половин матрицы:

    //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;
    }
1 голос
/ 27 мая 2011

выглядит примерно так:

for(row = 0; row < N; row++){  
   for(j = 0; j <= row; j++){  
      print Array[row - j][j];  
   }  
   newline;  
}  
1 голос
/ 27 мая 2011

Вот фрагмент кода 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();
}
0 голосов
/ 03 августа 2015

Вот одно из решений, которое я считаю полезным 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 ..
...