简体   繁体   中英

How to reverse a 2D array in java?

I am trying to reverse all of the content in a 2D array. The last value should be the first, and the first value should be the last.

For example, an input of

[1,2,3],
[4,5,6],
[7,8,9] 

would return:

[9,8,7]
[6,5,4]
[3,2,1]

This is some code I have so far, but it is returning this:

9 8 3 
6 5 4 
7 2 1 
int[][] reverse = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
for(int i = 0; i <= (reverse.length / 2); i++) {
    for(int j = 0; j < (reverse[0].length / 2) + 1; j++) {
        System.out.println(i + " " + j);
        System.out.println((reverse.length-1-i) + " " + (reverse[0].length -1 -j));
        int temp = reverse[reverse.length-1-i][reverse[0].length -1 -j];
        reverse[reverse.length-1-i][reverse[0].length - 1 - j] = reverse[i][j];
        reverse[i][j] = temp;
     }
}
for(int i = 0; i < reverse.length; i++) {
  for(int j = 0; j < reverse[0].length; j++) {
       System.out.print(reverse[i][j]+" ");
  }
  System.out.println("");
}

How can fix this so that the 3 and the 7 are switched?

You should write it to keep an x/y coordinate of the first cell and another x/y coordinate of the last cell, then swap the cell values. Advance the coordinates right/down and left/up, respectively until they meet.

The advantage is that the resulting code can handle jagged arrays too.

static void test(int[][] arr) {
    for (int y1 = 0, x1 = 0, y2 = arr.length - 1, x2 = arr[y2].length - 1; y1 < y2 || (y1 == y2 && x1 < x2); ) {
        int temp = arr[y1][x1];
        arr[y1][x1] = arr[y2][x2];
        arr[y2][x2] = temp;
        if (++x1 == arr[y1].length) {
            y1++;   x1 = 0;
        }
        if (x2-- == 0) {
            y2--;   x2 = arr[y2].length - 1;
        }
    }
    for (int y = 0; y < arr.length; y++) {
        for (int x = 0; x < arr[y].length; x++) {
            if (x != 0)
                System.out.print(" ");
            System.out.print(arr[y][x]);
        }
        System.out.println();
    }
}

Tests

test(new int[][] {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
test(new int[][] {{1, 2}, {3, 4, 5}, {6, 7, 8, 9}});

Output

9 8 7
6 5 4
3 2 1
9 8
7 6 5
4 3 2 1

The problem with your code is that you are looping through the 3. The outer loop goes from 0 to 1, and the inner loop goes from 0 to 2, so you only swap these elements with their corresponding element "on the other side":

1 2
4 5
7 8

You actually want to swap these with the elements on the other side instead:

1 2 3
4 

Basically, you need to find the half way point using the number of elements, not the number of rows and columns if you are going to swap elements.

int rows = reverse.length;
int cols = reverse[0].length;
int total = rows * cols;
int half = total / 2; // calculate halfway point

for(int n = 0; n < half; n++) {
  // convert the nth element to a coordinate
  int i = n / cols;
  int j = n % cols;

  int temp = reverse[rows - 1 - i][cols - 1 - j];
  reverse[rows- 1 - i][cols - 1 - j] = reverse[i][j];
  reverse[i][j] = temp;
}

If you are going to find the halfway point of rows and columns, then you should reverse the rows, and reverse the elements inside each row. I actually think this is a more intuitive approach.

int rows = reverse.length;
int cols = reverse[0].length;

// reverse the rows
for (int i = 0 ; i < rows / 2; i ++) {
  int[] temp = reverse[i];
  reverse[i] = reverse[rows - 1 - i];
  reverse[rows - 1 - i] = temp;
}

// for each row, reverse the elements inside the rows
for (int i = 0 ; i < rows; i ++) {
  for (int j = 0 ; j < cols / 2 ; j++) {
    int temp = reverse[i][j];
    reverse[i][j] = reverse[i][cols - 1 - j];
    reverse[i][cols - 1 - j] = temp;
  }
}

Your inner loop needs to iterate to the end of each row, rather than to the middle, and you need to handle the middle row of arrays with an odd number of rows separately:

static void reverse(int[][] arr)
{
    int m = arr.length;
    int n = arr[0].length;

    for(int i=0; i<m/2; i++)
        for(int j=0; j<n; j++)
            swap(arr[i], j, arr[m-1-i], n-1-j);
    
    if(m % 2 == 1) 
    {
        int[] mid = arr[m/2];
        for(int j=0; j<n/2; j++)
            swap(mid, j, mid, n-1-j);
    }
}
 


static void swap(int[] a, int i, int[] b, int j)
{
    int tmp = a[i];
    a[i] = b[j];
    b[j] = tmp;
}

Test:

int[][] arr = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
reverse(arr);       
for(int[] row : arr) System.out.println(Arrays.toString(row));

Output:

[9, 8, 7]
[6, 5, 4]
[3, 2, 1]

package algorithm_in_java_practice;

import java.util.Arrays; import java.util.Scanner;

public class _2DArray {

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in); 
    int m = sc.nextInt(); // row 
    int n = sc.nextInt(); // col
    
    int[][] arr = new int[m][n]; // array building with m*n
    
    // builing an array
    for(int i = 0; i < m; i++) {
        for(int j = 0; j < n; j++) {
            arr[i][j] = sc.nextInt();
        }
    }
    
   // Reverse an array
    for(int i = arr.length-1; i >= 0; i--) {
        for(int j = arr.length-1; j >= 0; j--) {
            System.out.print(arr[i][j] + " ");
        }
        System.out.println();
    }
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM