Antti Kolehmainen
Antti Kolehmainen

Reputation: 1091

Multi-dimensional array transposing

I have a row-based multidimensional array:

/** [row][column]. */
public int[][] tiles;

I would like to transform this array to column-based array, like following:

/** [column][row]. */
public int[][] tiles;

...But I really don't know where to start

Upvotes: 22

Views: 56150

Answers (12)

Stackbeans
Stackbeans

Reputation: 279

Here's what I came up with about a year ago, I was only just learning at the time so I came up with the solution within two weeks of learning Java.

We get a list of values:

int[] jest = new int[] {1, 2, 3, 4, 5, 6};

Then we produce empty double lists and get the length of the single list, and store these within the double list.

int[][] storeValues = null;
int[][] valueLength = new int[jest.length][jest.length];
int[][] submit = null;
int[][] submitted = null;

Create a double for-loop to increment a value until the length of the list. Then we store these and go over the array range to make it horizontal.

for(int i=0; i<jest.length;i++) {
        for(int j = 0; j < jest.length;j++) {
      
        storeValues = new int[][] {jest};
     valueLength[j][i] = storeValues[0][i];
     
     submit = Arrays.copyOfRange(valueLength, 0, j+1);
     
     submitted = Arrays.copyOfRange(submit, j, j+1);
    }   

Full working code:

import java.util.Arrays;

public class transMatrix {

    public static void main(String[] args) {
    int[] jest = new int[] {1, 2, 3, 4, 5, 6};
        int[][] storeValues = null;
        int[][] valueLength = new int[jest.length][jest.length];
        int[][] submit = null;
        int[][] submitted = null;
    for(int i=0; i<jest.length;i++) {
        for(int j = 0; j < jest.length;j++) {
      
        storeValues = new int[][] {jest};
     valueLength[j][i] = storeValues[0][i];
     
     submit = Arrays.copyOfRange(valueLength, 0, j+1);
     
     submitted = Arrays.copyOfRange(submit, j, j+1);
    }   
    
    }System.out.println(Arrays.deepToString(submitted)); 
}}

Output:

[[1, 2, 3, 4, 5, 6]]

Upvotes: -2

luk2302
luk2302

Reputation: 57124

The following solution does in fact return a transposed array instead of just printing it and works for all rectangular arrays, not just squares.

public int[][] transpose(int[][] array) {
    // empty or unset array, nothing do to here
    if (array == null || array.length == 0)
        return array;

    int width = array.length;
    int height = array[0].length;

    int[][] array_new = new int[height][width];

    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
            array_new[y][x] = array[x][y];
        }
    }
    return array_new;
}

you should call it for example via:

int[][] a = new int[][]{{1, 2, 3, 4}, {5, 6, 7, 8}};
for (int i = 0; i < a.length; i++) {
    System.out.print("[");
    for (int y = 0; y < a[0].length; y++) {
        System.out.print(a[i][y] + ",");
    }
    System.out.print("]\n");
}

a = transpose(a); // call
System.out.println();

for (int i = 0; i < a.length; i++) {
    System.out.print("[");
    for (int y = 0; y < a[0].length; y++) {
        System.out.print(a[i][y] + ",");
    }
    System.out.print("]\n");
}

which will as expected output:

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

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

Upvotes: 12

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

public class Demo {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        //asking number of rows from user
        int rows = askArray("Enter number of rows :", input);
        //asking number of columns from user
        int columns = askArray("Enter number of columns :", input);
        int[][] array = Array(rows, columns, input);
        //displaying initial matrix
        DisplayArray(array, rows, columns);
        System.out.println("Transpose array ");
        //calling Transpose array method
        int[][] array2 = TransposeArray(array, rows, columns);
        for (int i = 0; i < array[0].length; i++) {
            System.out.println(Arrays.toString(array2[i]));
        }
    }

    //method to take number of rows and number of columns from the user
    public static int askArray(String s, Scanner in) {
        System.out.print(s);
        int value = in.nextInt();

        return value;
    }

    //feeding elements to the matrix
    public static int[][] Array(int x, int y, Scanner input) {
        int[][] array = new int[x][y];
        for (int j = 0; j < x; j++) {
            System.out.print("Enter row number " + (j + 1) + ":");
            for (int i = 0; i < y; i++) {
                array[j][i] = input.nextInt();
            }
        }
        return array;
    }

    //Method to display initial matrix
    public static void DisplayArray(int[][] arra, int x, int y) {
        for (int i = 0; i < x; i++) {
            System.out.println(Arrays.toString(arra[i]));
        }
    }

    //Method to transpose matrix
    public static int[][] TransposeArray(int[][] arr, int x, int y) {
        int[][] Transpose_Array = new int[y][x];
        for (int i = 0; i < x; i++) {
            for (int j = 0; j < y; j++) {
                Transpose_Array[j][i] = arr[i][j];
            }
        }
        return Transpose_Array;
    }
}

Upvotes: 0

Vishnu Mari
Vishnu Mari

Reputation: 162

import java.util.*;

public class TestClass {
    public static void main(String args[]) throws Exception {
        Scanner in = new Scanner(System.in);
        int iSize = in.nextInt();
        int jSize = in.nextInt();
        int arr[][] = new int[iSize][jSize];
        int array[][] = new int[jSize][iSize];
        for (int i = 0; i < iSize; i++) {
            for (int j = 0; j < jSize; j++) {
                arr[i][j] = in.nextInt();
            }
            System.out.println("\n");
        }

        for (int n = 0; n < arr[0].length; n++) {
            for (int m = 0; m < arr.length; m++) {
                array[n][m] = arr[m][n];
                System.out.print(array[n][m] + " ");
            }
            System.out.print("\n");
        }
    }
}

Upvotes: -2

benez
benez

Reputation: 2001

a bit more generic way:

/**
 * Transposes the given array, swapping rows with columns. The given array might contain arrays as elements that are
 * not all of the same length. The returned array will have {@code null} values at those places.
 * 
 * @param <T>
 *            the type of the array
 * 
 * @param array
 *            the array
 * 
 * @return the transposed array
 * 
 * @throws NullPointerException
 *             if the given array is {@code null}
 */
public static <T> T[][] transpose(final T[][] array) {
    Objects.requireNonNull(array);
    // get y count
    final int yCount = Arrays.stream(array).mapToInt(a -> a.length).max().orElse(0);
    final int xCount = array.length;
    final Class<?> componentType = array.getClass().getComponentType().getComponentType();
    @SuppressWarnings("unchecked")
    final T[][] newArray = (T[][]) Array.newInstance(componentType, yCount, xCount);
    for (int x = 0; x < xCount; x++) {
        for (int y = 0; y < yCount; y++) {
            if (array[x] == null || y >= array[x].length) break;
            newArray[y][x] = array[x][y];
        }
    }
    return newArray;
}

Upvotes: 3

Jon Egeland
Jon Egeland

Reputation: 12613

public int[][] tiles, temp;

// Add values to tiles, wherever you end up doing that, then:
System.arraycopy(tiles, 0, temp, 0, tiles.length);

for (int row = 0; row < tiles.length; row++) // Loop over rows
    for (int col = 0; col < tiles[row].length; col++) // Loop over columns
        tiles[col][row] = temp[row][col]; // Rotate

That should do it for you.

Upvotes: 0

Zon
Zon

Reputation: 19880

Here is my 50 cents: a utility method and test to transponse multidimensional array (for doubles in my case):

/**
 * Transponse bidimensional array.
 *
 * @param original Original table.
 * @return Transponsed.
 */
public static double[][] transponse(double[][] original) {
    double[][] transponsed = new double
            [original[0].length]
            [original.length];

    for (int i = 0; i < original[0].length; i++) {
        for (int j = 0; j < original.length; j++) {
            transponsed[i][j] = original[j][i];
        }
    }
    return transponsed;
}
@Test
void aMatrix_OfTwoDimensions_ToBeTransponsed() {
    final double[][] original =
            new double[][]{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};

    double[][] transponsed = Analysis.transponse(original);

    assertThat(transponsed[1][2], is(equalTo(10)));
}

Upvotes: 0

Gilles Bodart
Gilles Bodart

Reputation: 614

public int[][] getTranspose() {
    int[][] transpose = new int[row][column];
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < column; j++) {
            transpose[i][j] = original[j][i];
        }
    }
    return transpose;
}

Upvotes: 0

Kent
Kent

Reputation: 195079

try this:

@Test
public void transpose() {
    final int[][] original = new int[][]{
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12}};

    for (int i = 0; i < original.length; i++) {
        for (int j = 0; j < original[i].length; j++) {
            System.out.print(original[i][j] + " ");
        }
        System.out.print("\n");
    }
    System.out.print("\n\n matrix transpose:\n");
    // transpose
    if (original.length > 0) {
        for (int i = 0; i < original[0].length; i++) {
            for (int j = 0; j < original.length; j++) {
                System.out.print(original[j][i] + " ");
            }
            System.out.print("\n");
        }
    }
}

output:

1 2 3 4 
5 6 7 8 
9 10 11 12 


 matrix transpose:
1 5 9 
2 6 10 
3 7 11 
4 8 12 

Upvotes: 8

Jash Sayani
Jash Sayani

Reputation: 1231

I saw that all of the answers create a new resultant matrix. This is simple:

matrix[i][j] = matrix[j][i];

However, you can also do this in-place, in case of square matrix.

// Transpose, where m == n
for (int i = 0; i < m; i++) {
    for (int j = i + 1; j < n; j++) {
        int temp = matrix[i][j];
        matrix[i][j] = matrix[j][i];
        matrix[j][i] = temp;
    }
}

This is better for larger matrices, where creating a new resultant matrix is wasteful in terms of memory. If its not square, you can create a new one with NxM dimensions and do the out of place method. Note: for in-place, take care of j = i + 1. It's not 0.

Upvotes: 17

Philomena Lamoureux
Philomena Lamoureux

Reputation: 1

Use this function (replace String by int if necessary). It takes the matrix as string array and returns a new matrix which is the transpose. It checks for the edge case of an empty array, too. No prints.

private String[][] transposeTable(String[][] table) {
    // Transpose of empty table is empty table
    if (table.length < 1) {
        return table;
    }

    // Table isn't empty
    int nRows = table.length;
    int nCols = table[0].length;
    String[][] transpose = new String[nCols][nRows];

    // Do the transpose
    for (int i = 0; i < nRows; i++) {
        for (int j = 0; j < nCols; j++) {
            transpose[j][i] = table[i][j];
        }
    }

    return transpose;
}

Upvotes: 0

Aniket Thakur
Aniket Thakur

Reputation: 68935

If you want to go for in place transpose of a matrix(in which case row count = col count) you can so following in Java

public static void inPlaceTranspose(int [][] matrix){

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

    for(int i=0;i<rows;i++){
        for(int j=i+1;j<cols;j++){
            matrix[i][j] = matrix[i][j] + matrix[j][i];
            matrix[j][i] = matrix[i][j] - matrix[j][i];
            matrix[i][j] = matrix[i][j] - matrix[j][i];
        }
    }
}

Upvotes: 1

Related Questions