从二维数组转置矩阵

Posted

技术标签:

【中文标题】从二维数组转置矩阵【英文标题】:Transposing a matrix from a 2D array 【发布时间】:2014-11-29 14:31:24 【问题描述】:

我正在自学一些 java,我坚持创建一个二维数组,用随机值对其进行初始化,然后创建数组的转置。

一个示例输出是:

$ 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.

原始矩阵

  1  22  
333  44  
555   6

转置矩阵

  1  333  555`  
 22   44    6`

^ 应该是最终输出。一些有关代码的帮助将不胜感激!

如果行数或列数超出指定范围,我想编写代码以生成错误消息。如果从命令行读取矩阵元素而不是随机生成它们。

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...
    

【问题讨论】:

如果您发布您尝试过的代码,您将获得更好的帮助。我们无法判断您是否在输入字符串、验证输入或转置数组元素时遇到问题。 我在这里没有看到任何矩阵。请让您的帖子更具可读性。您正在尝试线性显示二维矩阵 抱歉,我在第一篇文章中添加了我正在处理的代码。我知道它需要一些修改,但我不确定如何实现它们 我不知道为什么它呈线性显示......它不应该 您在哪一部分遇到了问题? 【参考方案1】:

这是一个返回转置矩阵的 int[][] 的简单方法...

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;

除了打印二维矩阵,您还可以使用如下方法:

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;

【讨论】:

上述方案只适用于方阵,不适用于M和N不同的矩阵。【参考方案2】:

上面提供的答案在内存方面效率不高。它使用另一个数组 - transposedMatrix 除了作为参数提供的数组。这将导致消耗双倍内存。我们可以按如下方式就地执行此操作:

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();
        
       

【讨论】:

这不会返回矩形矩阵的转置。【参考方案3】:

你可以使用下面的类,它有你想要的大部分方法。

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

输出:

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

【讨论】:

【参考方案4】:

对于方阵,无需遍历整个数组,您只需遍历 2D 数组的对角一半并将值与相应的索引交换。

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;
            
        

【讨论】:

【参考方案5】:

这是 Kotlin 解决方案!

fun displayMatrix(matrix: Array<IntArray>) 
    for(row in matrix) 
        for(column in row) 
            print("$column  ")
        
        println()
    


fun main() 

//Create Array
val matrixA = arrayOf(intArrayOf(2, 3, 4), intArrayOf(5, 6, 4), intArrayOf(1, 6, 7), intArrayOf(0, 2, 8))

println("Dimension on X: $matrixA[0].size")
println("Dimension on Y: $matrixA.size")

displayMatrix(matrixA)

println()

val transposeMatrix = Array(matrixA[0].size)  IntArray(matrixA.size) 


for(i in 0..matrixA.size - 1) 
    for(j in 0..matrixA[0].size - 1) 
        transposeMatrix[j][i] = matrixA[i][j]
    


displayMatrix(transposeMatrix)



【讨论】:

【参考方案6】:

n x m 矩阵的另一种 Kotlin 解决方案

fun transpose(matrix: Array<Array<Double>>): Array<Array<Double>> 
    return matrix[0].mapIndexed  col, _ ->
        matrix.mapIndexed  row, _ ->
            matrix[row][col]
        .toTypedArray()
    .toTypedArray()


fun printMatrix(matrix: Array<Array<Double>>) 
    println(matrix.joinToString("\n")  it.contentToString() )


fun main() 
    val matrix = arrayOf(
        arrayOf( 1.0,  2.0,  3.0),
        arrayOf( 4.0,  5.0,  6.0),
        arrayOf( 7.0,  8.0,  9.0),
        arrayOf( 1.0,  2.0,  3.0),
    )
    println("matrix:")
    printMatrix(matrix)
    println("transpose(matrix):")
    printMatrix(transpose(matrix))

输出

matrix:
[1.0, 2.0, 3.0]
[4.0, 5.0, 6.0]
[7.0, 8.0, 9.0]
[1.0, 2.0, 3.0]
transpose(matrix):
[1.0, 4.0, 7.0, 1.0]
[2.0, 5.0, 8.0, 2.0]
[3.0, 6.0, 9.0, 3.0]

在Kotlin Playground试试吧

【讨论】:

以上是关于从二维数组转置矩阵的主要内容,如果未能解决你的问题,请参考以下文章

二维动态数组转置

013.用二维数组实现矩阵转置

稀疏矩阵转置

C代码和python代码:用二维数组实现矩阵的转置

矩阵与转置

使用循环平铺转置大型二维矩阵没有性能提升