使用 for 循环反转二维数组

问题描述

我自学了大约 6 个月的 Java,所以我对编码还很陌生,我需要你的帮助。 我想使用 2 个循环完全反转一个二维数组 (a) 并将其写入另一个数组,但是当我尝试更改行和列值时出现 OutOfBondsError。似乎我不完全理解这些嵌套循环是如何工作的...

起始数组a:

1.) 1.0  2.0  3.0  2.0
2.) 0.0  1.0  2.0  0.0
3.) 0.0  0.0  1.0  3.0

我的代码应该像这样反转。

目标数组t:

1.) 3.0  1.0  0.0  0.0
2.) 0.0  2.0  1.0  0.0
3.) 2.0  3.0  2.0  1.0
final double[][] a = new double[3][];

a[0] = new double[]{1,2,3,2}; // I
a[1] = new double[]{0,1,0}; // II
a[2] = new double[]{0,3}; // III

int numLines = a.length;
int numCols = a[0].length;

double[][] t = new double[a.length][a[0].length];
for (int currentColumn = numCols - 2; currentColumn >= 0; currentColumn--) {
    for (int currentLine = numLines - 1; currentLine >= 0; currentLine--) {
        t[currentLine][currentColumn] = a[currentColumn][currentLine];
    }
    System.out.println();
}
ArrayTools.printMatrix(t);

数组 t 的 printMatrix 方法的控制台输出如下所示:

1.) 1.0  0.0  0.0  0.0
2.) 2.0  1.0  0.0  0.0
3.) 3.0  2.0  1.0  0.0

这与我想要的非常接近,但我不知道如何从写入的 t 中获取最后一列。

如果你们能向我解释这里发生了什么以及如何解决这个问题,我会很高兴!

解决方法

您可以使用 streams 来反转二维数组。首先展平一个源阵列并反转它,然后从反转的平面阵列中收集回一个二维阵列:

// dimensions
int m = 3;
int n = 4;

// source array
double[][] arr1 = {
        {1.0,2.0,3.0,2.0},{0.0,1.0,0.0},0.0,3.0}};

// flat array
Double[] arr2 = Arrays.stream(arr1)
        .flatMapToDouble(Arrays::stream)
        .boxed()
        .toArray(Double[]::new);
// reverse a flat array
Collections.reverse(Arrays.asList(arr2));

// collect a 2d array from a reversed 1d array
double[][] arr3 = IntStream.range(0,m)
        .mapToObj(i -> Arrays
                .stream(arr2,i * n,i * n + n)
                .mapToDouble(Double::doubleValue)
                .toArray())
        .toArray(double[][]::new);
// output
Arrays.stream(arr3).map(Arrays::toString).forEach(System.out::println);
[3.0,0.0]
[0.0,0.0]
[2.0,1.0]

另见:Sorting through entire 2d array in ascending order

,

您正在做的是(的一部分)移调。您应该反转行和列。

int numLines = a.length;
int numCols = a[0].length;

double[][] t = new double[a.length][a[0].length];
for (int currentLine = 0; currentLine < numLines; currentLine++) {
    for (int currentColumn = 0; currentColumn < numCols; currentColumn++) {
        t[currentLine][currentColumn] =
                a[numLines - 1 - currentLine][numCols - 1 - currentColumn];
    }
}
,

您首先将“行”用作第一个括号,将“列”用作第二个:

int numLines = a.length;
int numCols = a[0].length;

但你后来反过来使用它们:

a[currentColumn][currentLine];

您只需要将其反转为:

int numLines = a[0].length;
int numCols = a.length;

或者:

double[][] t = new double[a[0].length][a.length];
t[currentColumn][currentLine] = a[currentLine][currentColumn];
,

您可以向后遍历这个二维数组的行的索引,然后 clone 原始行,然后反转它们:

double[][] arr = {
        {1.0,3.0}};
double[][] nArr = IntStream
        // iterate backwards through the indexes of the array rows
        .iterate(arr.length - 1,i -> i >= 0,i -> i = i - 1)
        // take the copy the row by its index
        .mapToObj(i -> arr[i].clone())
        // reverse the elements of the row
        .peek(row -> {
            // iterate to the middle of the row and swap the elements:
            // first and last,second and penultimate,and so on
            for (int i = 0; i < row.length / 2; i++) {
                double temp = row[i];
                row[i] = row[row.length - i - 1];
                row[row.length - i - 1] = temp;
            }
            // return a new array
        }).toArray(double[][]::new);
// output
Arrays.stream(nArr).map(Arrays::toString).forEach(System.out::println);
[3.0,1.0]