Пересечение массива по диагонали

у меня большой массив произвольного размера. Это квадратный массив. Я пытаюсь понять, как пройти по диагонали, как /, а не (что я уже умею делать). До сих пор у меня есть следующий код:

char[][] array = new char[500][500];
//array full of random letters
String arrayLine = "";
for (int y = 0; y < array.length; y++) {
    for (int x = 0; x < array.length; x++) {
        for (???) {
            arrayLine = arrayLine + array[???][???];
        }
    }
    System.out.println(arrayLine);
}

у меня три петли, потому что так я сделал другую диагональ:

for (int y = 0; y < array.length; y++) {
    for (int x = 0; x < array.length; x++) {
        for (int z = 0; z < array.length-y-x; z++) {
            arrayLine = arrayLine + array[y+z][x+z];
        }
    }
    System.out.println(arrayLine);
}

в моих попытках я продолжаю выходить за пределы границ и получаю исключение ElementOutOfBounds. Скажем, массив, как показано ниже (3x3 вместо 500x500):

A B C
D E F
G H I

Я хочу распечатать следующие строки:

A
BD
CEG
FH
I

предыдущий вопрос SO имел аналогичную проблему с целочисленными массивами, и решение основано на сумме элементов массива. Но я работаю с chars, поэтому я не могу придумать методологию, чтобы получить его.

2 ответов


подумайте о координатах ячеек:

. 0 1 2
0 A B C
1 D E F
2 G H I

для любой диагонали все элементы имеют что-то общее: сумма координат элемента является константой. Вот константы:

0 = 0+0 (A)
1 = 1+0 (B) = 0+1 (D)
2 = 2+0 (C) = 1+1 (E) = 0+2 (G)
3 = 2+1 (F) = 1+2 (H)
4 = 2+2 (I)

минимальная константа-наименьшая сумма координат, 0. Максимальная константа-это наибольшая сумма координат. Так как каждый координатный компонент может доходить до array.length - 1 максимальная константа 2 * (array.length - 1).

Итак, что нужно сделать, это перебрать над константами. Для каждой константы повторите элементы, координаты которых суммируются с константой. Это, пожалуй, самый простой подход:

for (int k = 0; k <= 2 * (array.length - 1); ++k) {
    for (int y = 0; y < array.length; ++y) {
        int x = k - y;
        if (x < 0 || x >= array.length) {
            // Coordinates are out of bounds; skip.
        } else {
            System.out.print(array[y][x]);
        }
    }
    System.out.println();
}

однако это приведет к итерации по множеству внешних координат, потому что он всегда повторяет все возможные y координаты, хотя только одна диагональ содержит все возможные y координаты. Давайте изменим y цикл, поэтому он посещает только y координаты, необходимые для текущего k.

одно условие для внешних координат -x < 0. Заменить определение x и решить:

x < 0
k - y < 0
k < y
y > k

когда y > k, x будет отрицательным. Таким образом, мы хотим только цикл while y <= k.

другое условие для внешних координат -x >= array.length. Решить:

x >= array.length
k - y >= array.length
k - array.length >= y
y <= k - array.length

когда y <= k - array.length, x будет слишком большой. Таким образом, мы хотим начать y 0 или k - array.length + 1 в зависимости от больше.

for (int k = 0; k <= 2 * (array.length - 1); ++k) {
    int yMin = Math.max(0, k - array.length + 1);
    int yMax = Math.min(array.length - 1, k);
    for (int y = yMin; y <= yMax; ++y) {
        int x = k - y;
        System.out.print(array[y][x]);
    }
    System.out.println();
}

примечание: Я только доказал правильность этого кода. Я не проверял его.


гораздо проще проверить сумму, если индексы равны массиву.длина = 1; для diagonalRight и для diagonalLeft просто проверьте, равен ли i j

пример:

суммы digonalLeft \ матрицы, потому что (0,0) (1,1) (2,2) делает диагональ. диагональные суммы / матрицы, потому что (0+2) = (1+1) = (2+0) = 2 и 2-это массив.длина - 1.

long diagonalLeft = 0;
long diagonalRight = 0;

for (int i = 0; i < array.lenth - 1; i++) {
    for (int j = 0; j < array.length -1; j++) {
        if (i == j) digonalLeft += array[i][j];
        if (i + j == array.length - 1) diagonalRight += array[i][j];
    }    
}