Reputation: 17
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?
Upvotes: 1
Views: 2388
Reputation: 338
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();
}
}
}
Upvotes: 0
Reputation: 159096
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
Upvotes: 2
Reputation: 5455
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]
Upvotes: 0
Reputation: 271515
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;
}
}
Upvotes: 0