0

I am teaching myself Java for about 6 months so I am pretty new to coding and I need your help here. I want to completely reverse a 2 dimensional array (a) using 2 loops and writing it in another array but I get an OutOfBondsError as I tried to change my line and column values. It seems like I don't fully understand how these nested loops work...

starting array 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

My code should reverse a like this.

Target array 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, 2, 0}; // II
a[2] = new double[]{0, 0, 1, 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);

The console output from my printMatrix method for array t looks like this:

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

It's pretty close to what I want but I dont know how to get the last colum from a written into t.

I would be happy if you guys could explain me what happens here and how to slove this problem!

4 Answers4

0

What you are doing is (a part of) transposing. You should reverse rows and columns.

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];
    }
}
Community
  • 1
  • 1
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
0

You are first using "lines" as the first bracket and "columns" as the second:

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

But you are later using them the other way around:

a[currentColumn][currentLine];

You just need to reverse it as:

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

Or:

double[][] t = new double[a[0].length][a.length];
t[currentColumn][currentLine] = a[currentLine][currentColumn];
Community
  • 1
  • 1
dajavax
  • 3,060
  • 1
  • 14
  • 14
0

You can use streams to reverse a 2d array. First flatten a source array and reverse it, then collect back a 2d array from a reversed flat array:

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

// source array
double[][] arr1 = {
        {1.0, 2.0, 3.0, 2.0},
        {0.0, 1.0, 2.0, 0.0},
        {0.0, 0.0, 1.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, 1.0, 0.0, 0.0]
[0.0, 2.0, 1.0, 0.0]
[2.0, 3.0, 2.0, 1.0]

See also: Sorting through entire 2d array in ascending order

0

You can iterate backwards through the indexes of the rows of this 2d array, then clone the original rows, and then reverse them:

double[][] arr = {
        {1.0, 2.0, 3.0, 2.0},
        {0.0, 1.0, 2.0, 0.0},
        {0.0, 0.0, 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, 0.0, 0.0]
[0.0, 2.0, 1.0, 0.0]
[2.0, 3.0, 2.0, 1.0]