Отразить одномерное представление массива по оси 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;
}