Отразить одномерное представление массива по оси X

Я занимаюсь программированием шахматного ИИ и столкнулся с проблемой, связанной с реализацией таблиц с квадратными фигурами. Так как я хочу иметь только одну квадратную таблицу на каждую сторону, мне нужна функция, чтобы перевернуть одномерный массив, который содержит значения вокруг оси x. Например, этот массив:

[ 2, 4, 5, 3, 5, 0, 1, 4, 2 ]

будет переключено на:

[ 1, 4, 2, 3, 5, 0, 2, 4, 5 ]

Я добился этого для массива 0x64, используя вложенные циклы, используя следующий метод (примечание: пример был только 3x3, но следующая функция настраивается на 8x8); Однако мне было интересно, есть ли что-то более эффективное, поскольку время вызывает беспокойство.

public int[] gridFromPerspective(int[] grid){

    int[] flippedGrid = new int[64];

    for(int i = 7; i < 32; i += 8){
        for(int j = 0; j < 8; j++){
            flippedGrid[i-j] = grid[63-(i-j)];
            flippedGrid[63-(i-j)] = grid[i-j];
        }
    }
}

Я знаю, что вы можете легко и эффективно перевернуть доску sq' = sq ^ 56, но я не уверен, как я могу использовать эту технику в случае одномерного массива. Любой совет будет оценен.

2 ответа

Решение

Метод, который вы используете, на самом деле не переворачивает доску вокруг оси X, а скорее вращает доску целиком. По сути, grid[0] всегда будет иметь то же значение, что и flippedGrid[63], Если вы хотите посмотреть на доску с точки зрения других игроков, это на самом деле правильно, однако вы можете уменьшить свои петли до

for (int i = 0; i < 64; i++) {
    flippedGrid[i] = grid[63-i];
}

Это должно обеспечить (очень) небольшое увеличение производительности.

Однако если вы действительно хотите перевернуть доску вокруг оси X, вы можете использовать System.arraycopyчтобы получить повышение производительности:

for (int i = 0; i < 8; i++) {
    System.arraycopy(grid, 8*i, flippedGrid, 64 - 8*(i+1), 8);
}

Таким образом, вместо того, чтобы копировать отдельные значения, вы позволяете JVM копировать куски длиной 8 (строка) сразу.

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

Вот немного более простая версия, которая не жестко кодирует размер сетки.

private static int[] flipVertically(int[] grid) {
    final int width = (int)Math.sqrt(grid.length);
    int[] flippedGrid = new int[grid.length];
    for (int i = 0; i < grid.length; i += width)
        System.arraycopy(grid, i, flippedGrid, grid.length - width - i, width);
    return flippedGrid;
}
Другие вопросы по тегам