如何将 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 度以后的矩阵(更新中)