如何将 N x N 矩阵旋转 90 度? [关闭]

Posted

技术标签:

【中文标题】如何将 N x N 矩阵旋转 90 度? [关闭]【英文标题】:How to rotate a N x N matrix by 90 degrees? [closed] 【发布时间】:2010-05-23 19:27:35 【问题描述】:

如何将 N x N 矩阵旋转 90 度。我希望它就位?

【问题讨论】:

How do you rotate a two dimensional array? 的重复(这些解决方案中的代码大多不是 C++,但算法很简单,在大多数情况下转换为 C++ 应该是微不足道的) 这取决于矩阵在数据结构中的存储方式。到目前为止,您尝试过什么? 顺时针还是逆时针? 顺时针方向,请确保不要创建额外的矩阵。 @James,您链接到的问题不需要就地轮换,并且没有一个答案表明这样的解决方案。 【参考方案1】:
for(int i=0; i<n/2; i++)
   for(int j=0; j<(n+1)/2; j++)
       cyclic_roll(m[i][j], m[n-1-j][i], m[n-1-i][n-1-j], m[j][n-1-i]);


void cyclic_roll(int &a, int &b, int &c, int &d)

   int temp = a;
   a = b;
   b = c;
   c = d;
   d = temp;

注意这个我没有测试过,只是现在当场作曲。请在使用它之前进行测试。

【讨论】:

解释索引.. 好吧,想想当旋转 90 度时 (i,j) 的位置在哪里。想象一下图片。 (i,j)->(end-j,i)。与原始矩阵的左侧一样高,与矩阵底部的左侧一样远。 如果逆时针旋转,则映射为a[p][k] --> a[N-1-k][p] --> a[N-1-p] [N-1-k] --> a[k][N-1-p]。我认为 i 的约束也有错误。它应该是 for 循环中的 i 我无法编辑。代码应该是 for(int i=0; i cyclic_roll 函数的第三个参数仍然需要更正。它应该是 [n-1-i][n-1-j] :) 好吧,Pavel……你逆时针旋转,对吗?我认为 OP 要求顺时针旋转,所以我只想指出,无论谁在看这个答案,都应该记住这一点,而不是盲目地复制和粘贴:)。【参考方案2】:

这是我的解决方案: (顺时针旋转 pi/2)

    对数组进行转置,(如矩阵转置)

    反转每一行的元素

    cons int row = 10;
    cons int col = 10;
    //transpose
    for(int r = 0; r < row; r++) 
      for(int c = r; c < col; c++)   
        swap(Array[r][c], Array[c][r]);
      
    
    //reverse elements on row order
    for(int r = 0; r < row; r++) 
        for(int c =0; c < col/2; c++) 
          swap(Array[r][c], Array[r][col-c-1])
        
    
    

如果逆时针旋转 pi/2

    转置数组

    按列顺序反转元素

永远不要测试代码! 任何建议将不胜感激!

【讨论】:

每个元素将被移动两次(与@Pavel Radzivilovsky 的回答中的 1.25 次相比),因此效率较低。 “好处”是因为不需要int temp,内存需求减少了所有四个字节...... 同意@Jean-FrançoisCorbett 不如其他答案有效。但是,这个肯定更简单。其实我也实现了同样的算法!! 感谢这大大简化了解决方案【参考方案3】:

一个完整的 C 程序,说明了我的方法。本质上它是递归算法。在每次递归时,您都会旋转外层。当您的矩阵为 1x1 或 0x0 时停止。

#include <stdio.h>

int matrix[4][4] = 
     11, 12, 13, 14,
     21, 22, 23, 24,
     31, 32, 33, 34,
     41, 42, 43, 44 
;

void print_matrix(int n)

   for (int i = 0; i < n; i++) 
      for (int j = 0; j < n; j++) 
         printf(" %d ", matrix[i][j]);
      
      printf("\n");
   


int *get(int offset, int x, int y)

   return &matrix[offset + x][offset + y];


void transpose(int offset, int n)

   if (n > 1) 
      for (int i = 0; i < n - 1; i++) 
         int *val1 = get(offset, 0, i);
         int *val2 = get(offset, i, n - 1);
         int *val3 = get(offset, n - 1, n - 1 - i);
         int *val4 = get(offset, n - 1 - i, 0);

         int temp = *val1;
         *val1 = *val4;
         *val4 = *val3;
         *val3 = *val2;
         *val2 = temp;
      

      transpose(offset + 1, n - 2);
   


main(int argc, char *argv[])

   print_matrix(4);
   transpose(0, 4);
   print_matrix(4);
   return 0;

【讨论】:

【参考方案4】:
//Java version, fully tested

public class Rotate90degree 


        public static void reverseElementsRowWise(int[][] matrix) 
            int n = matrix.length;
            for(int i = 0; i < n; ++i) 
                for(int j = 0; j < n / 2; ++j) 
                    int temp = matrix[i][n - j - 1];
                    matrix[i][n - j - 1] = matrix[i][j];
                    matrix[i][j] = temp;
                
            
        

        public static void transpose(int[][] matrix) 
            int n = matrix.length;
            for(int i = 0; i < n; ++i) 
                for(int j = i + 1; j < n; ++j) 
                    int temp = matrix[i][j];
                    matrix[i][j] = matrix[j][i];
                    matrix[j][i] = temp;
                
            
        

        public static void rotate90(int[][] matrix) 
            transpose(matrix);
            reverseElementsRowWise(matrix);
        

        public static void print(int[][] matrix) 
            int n = matrix.length;
            for(int i = 0; i < n; ++i) 
                for(int j = 0; j < n; ++j) 
                    System.out.print(matrix[i][j]);
                    System.out.print(' ');
                
                System.out.println();
            
        

        public static void main(String[] args) 
            int[][] matrix = 
                    1, 2, 3, 4,
                    5, 6, 7, 8,
                    9, 10, 11, 12,
                    13, 14, 15, 16;
            System.out.println("before");
            print(matrix);
            rotate90(matrix);
            System.out.println("after");
            print(matrix);
        

【讨论】:

【参考方案5】:

您可以创建第二个数组,然后通过读取第一个数组中的行优先并将列优先写入第二个数组,将第一个数组复制到第二个数组中。

所以你会复制:

1  2  3
4  5  6
7  8  9

你会读第一行然后把它写回来,像这样开始:

3
2
1

【讨论】:

以上是关于如何将 N x N 矩阵旋转 90 度? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

第34题给定一个 n X n 的矩阵 和 R,求旋转 90R 度以后的矩阵(更新中)

给定一个 n × n 的二维矩阵表示一个图像, 将图像顺时针旋转 90 度js实现

Leecode-48:旋转图像(矩阵顺时针旋转90度)

矩阵、虚数与坐标变换

矩阵旋转90度

python——n*n矩阵顺时针旋转90度