Transposing a matrix from a 2D array

38,611

Solution 1

This is a simple method that return an int[][] of the transposed matrix...

public static int[][] transposeMatrix(int[][] matrix){
    int m = matrix.length;
    int n = matrix[0].length;

    int[][] transposedMatrix = new int[n][m];

    for(int x = 0; x < n; x++) {
        for(int y = 0; y < m; y++) {
            transposedMatrix[x][y] = matrix[y][x];
        }
    }

    return transposedMatrix;
}

Than to print a 2D matrix you can use a method like this:

public static String matrixToString(int[][] a){
    int m = a.length;
    int n = a[0].length;

    String tmp = "";
    for(int y = 0; y<m; y++){
        for(int x = 0; x<n; x++){
            tmp = tmp + a[y][x] + " ";
        }
        tmp = tmp + "\n";
    }

    return tmp;
}

Solution 2

The answer provided above is not efficient in terms of memory. It is using another array - transposedMatrix apart from array supplied as argument. This will lead to consume double memory. We can do this in-place as follows:

public void transposeMatrix(int[][] a)
{
        int temp;
        for(int i=0 ; i<(a.length/2 + 1); i++)
        {
            for(int j=i ; j<(a[0].length) ; j++)
            {
                temp = a[i][j];
                a[i][j] = a[j][i];
                a[j][i] = temp;
            }
        }

        displayMatrix(a);
    }

public void displayMatrix(int[][] a){
        for(int i=0 ; i<a.length ; i++)
        {
            for(int j=0 ; j<a[0].length ; j++)
            {
                System.out.print(a[i][j] + " ");
            }

            System.out.println();
        }
    }   

Solution 3

You can use the below class it has most of the methods you want.

/**
 * Class representing square matrix of given size.
 * It has methods to rotate by 90, 180 and 270
 * And also to transpose and flip on either axis.
 * 
 * I have used both space efficient methods in transpose and flip
 * And simple but more space usage for rotation. 
 * 
 * This is using builder pattern hence, you can keep on applying
 * methods say rotate90().rotate90() to get 180 turn.
 * 
 */
public class Matrix {

    private int[][] matrix;
    final int size;

    public Matrix(final int size) {
        this.size = size;
        matrix = new int[size][size];

        for (int i=0;i<size;i++)
            for (int j=0;j<size;j++)
                matrix[i][j] = i*size + j;
    }

    public Matrix rotate90() {
        int[][] temp = new int[size][size];

        for (int i=0;i<size;i++)
            for (int j=0;j<size;j++)
                temp[i][j] = matrix[size-1-j][i];

        matrix = temp;
        return this;
    }
    public Matrix rotate180() {
        int[][] temp = new int[size][size];

        for (int i=0;i<size;i++)
            for (int j=0;j<size;j++)
                temp[i][j] = matrix[size-1-i][size-1-j];

        matrix = temp;
        return this;
    }
    public Matrix rotate270() {
        int[][] temp = new int[size][size];

        for (int i=0;i<size;i++)
            for (int j=0;j<size;j++)
                temp[i][j] = matrix[j][size-1-i];

        matrix = temp;
        return this;
    }
    public Matrix transpose() {
        for (int i=0; i<size-1; i++) {
            for (int j=i+1; j<size; j++) {
                int tmp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = tmp;
            }
        }
        return this;
    }
    public Matrix flipVertical() {
        for (int i=0; i<size; i++) {
            for (int j=0; j<size/2; j++) {
                int tmp = matrix[i][size-1-j];
                matrix[i][size-1-j] = matrix[i][j];
                matrix[i][j] = tmp;
            }
        }
        return this;
    }
    public Matrix flipHorizontal() {
        for (int i=0; i<size/2; i++) {
            for (int j=0; j<size; j++) {
                int tmp = matrix[size-1-i][j];
                matrix[size-1-i][j] = matrix[i][j];
                matrix[i][j] = tmp;
            }
        }
        return this;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (int i=0;i<size;i++) {
            for (int j=0;j<size;j++) {
                sb.append("|");
                sb.append(matrix[i][j]);
                if (size > 3) {
                    sb.append("\t");
                }
            }
            sb.append("|\n");
        }

        return sb.toString();
    }

    public static void main(String... args) {
        Matrix m = new Matrix(3);
        System.out.println(m);

        //transpose and flipHorizontal is 270 turn (-90)
        System.out.println(m.transpose());
        System.out.println(m.flipHorizontal());

        //rotate 90 further to bring it back to original position
        System.out.println(m.rotate90());

        //transpose and flip Vertical is 90 degree turn
        System.out.println(m.transpose().flipVertical());
    }
}

Output:

|0|1|2|
|3|4|5|
|6|7|8|

|0|3|6|
|1|4|7|
|2|5|8|

|2|5|8|
|1|4|7|
|0|3|6|

|0|1|2|
|3|4|5|
|6|7|8|

|6|3|0|
|7|4|1|
|8|5|2|

Solution 4

For a square matrix, instead of iterating through the entire array, you just iterate through the diagonally half of the 2D array and swap the values with the corresponding indices.

public void transposeMatrix(int[][] a) {
        for(int i=0 ; i<n; i++) { 
            for(int j=0 ; j<i ; j++) {
                int temp = a[i][j];
                a[i][j] = a[j][i];
                a[j][i] = temp;
            }
        }
}
Share:
38,611
Admin
Author by

Admin

Updated on July 05, 2022

Comments

  • Admin
    Admin almost 2 years

    I'm self teaching myself some java and I'm stuck on creating a 2D array that initializes it with random values and then creates the transpose of the array.

    An example output is:

    $ java Test1 22 333 44 555 6  
    Enter the number of rows (1-10): 0  
    ERROR: number not in specified range (1-10) !  
    and so on until you enter the correct number of rows and columns.
    

    Original matrix

      1  22  
    333  44  
    555   6
    

    Transposed matrix

      1  333  555`  
     22   44    6`
    

    ^ Should be the final output. Some help with the code would appreciated!

    I would like to code to generate error messages if the number of rows or columns is outside the specified range. And for if to read the matrix elements from the command line and not generate them randomly.

    import java.util.Scanner;
    
    public class Test1 {
        /** Main method */
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            System.out.print("Enter the number of rows (1-10): ");
            int rows = input.nextInt();
            System.out.print("Enter the number of columns (1-10): ");
            int cols = input.nextInt();
    
            // Create originalMatrix as rectangular two dimensional array
            int[][] originalMatrix = new int[rows][cols];
    
            // Assign random values to originalMatrix
            for (int row = 0; row < originalMatrix.length; row++)
                for (int col = 0; col < originalMatrix[row].length; col++) {
                    originalMatrix[row][col] = (int) (Math.random() * 1000);
                }
    
            // Print original matrix
            System.out.println("\nOriginal matrix:");
            printMatrix(originalMatrix);
    
            // Transpose matrix
            int[][] resultMatrix = transposeMatrix(originalMatrix);
    
    
            // Print transposed matrix
            System.out.println("\nTransposed matrix:");
            printMatrix(resultMatrix);
        }
    
        /** The method for printing the contents of a matrix */
        public static void printMatrix(int[][] matrix) {
            for (int row = 0; row < matrix.length; row++) {
                for (int col = 0; col < matrix[row].length; col++) {
                    System.out.print(matrix[row][col] + "  ");
                }
                System.out.println();
            } 
        }
    
        /** The method for transposing a matrix */
        public static int[][] transposeMatrix(int[][] matrix) {
            // Code goes here...
        }
    }