【问题标题】:Multi-dimensional array transposing多维数组转置
【发布时间】:2012-01-15 09:08:35
【问题描述】:

我有一个基于行的多维数组:

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

我想将此数组转换为基于列的数组,如下所示:

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

...但我真的不知道从哪里开始

【问题讨论】:

    标签: java arrays matrix multidimensional-array transpose


    【解决方案1】:
    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
    

    这应该为你做。

    【讨论】:

    • 那行不通。您可能正在考虑 C 或 C++;在 Java 中,temp = tiles 使 tilestemp 成为对 same 数组的引用,而您已经完全搞定了。 :-P
    • 它做错了什么?它不编译吗?不复制数组?什么?
    • 好吧,它不能编译——tmp 应该是temp。然后,您也永远不会实例化temp(我假设tiles 来自某个外部源)。但即使修复了这些,它也会将[[1, 2], [3, 4]] 变成[[1, 2], [2, 4]]。如果矩阵是矩形而不是正方形(即,N x M instad of N x N),它将抛出 ArrayIndexOutOfBoundsException
    【解决方案2】:

    试试这个:

    @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");
            }
        }
    }
    

    输出:

    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 
    

    【讨论】:

    • 这只会打印出更改。它实际上并没有改变数组。
    • 不,它没有改变数组,只是展示了循环是如何工作的
    【解决方案3】:

    以下解决方案实际上确实返回了一个转置数组,而不仅仅是打印它,并且适用于所有矩形数组,而不仅仅是正方形。

    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;
    }
    

    您应该通过以下方式调用它:

    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");
    }
    

    这将是预期的输出:

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

    【讨论】:

      【解决方案4】:

      我看到所有答案都创建了一个新的结果矩阵。这很简单:

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

      但是,如果是方阵,您也可以就地执行此操作。

      // 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;
          }
      }
      

      这对于较大的矩阵更好,因为创建一个新的结果矩阵在内存方面是浪费的。如果它不是方形的,您可以创建一个具有NxM 尺寸的新的并执行不合适的方法。注意:对于就地,请注意j = i + 1。不是0

      【讨论】:

      • 为什么是 j + 1 而不是 0?我想它避免了多余的步骤,但我的代码在我初始化我的 j 变量后开始工作,就像你做的那样,而不是 0...除了我有相同的代码
      • @AlfredoGallegos 这不是“只是”多余的,如果你做额外的步骤你做额外的交换,这意味着如果你交换两次你基本上没有交换任何东西。
      【解决方案5】:

      如果你想对矩阵进行就地转置(在这种情况下是 row count = col count),你可以在 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];
              }
          }
      }
      

      【讨论】:

        【解决方案6】:
        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;
            }
        }
        

        【讨论】:

          【解决方案7】:
          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;
          }
          

          【讨论】:

            【解决方案8】:

            更通用的方式:

            /**
             * 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;
            }
            

            【讨论】:

              【解决方案9】:
              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");
                      }
                  }
              }
              

              【讨论】:

                【解决方案10】:

                使用此函数(如有必要,将 String 替换为 int)。它将矩阵作为字符串数组并返回一个新矩阵,即转置。它也检查空数组的边缘情况。没有指纹。

                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;
                }
                

                【讨论】:

                • 请提供此代码的解释以及它如何回答问题
                【解决方案11】:

                这是我的 50 美分:用于转置多维数组的实用方法和测试(在我的例子中是双精度数):

                /**
                 * 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)));
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2010-10-22
                  • 2011-02-10
                  • 1970-01-01
                  • 2010-11-29
                  • 2016-11-16
                  相关资源
                  最近更新 更多