目录👈(゚ヮ゚👈
前言
在处理矩阵(包括非方阵)时,常见的操作包括翻转和旋转。本文将详细介绍如何通过代码实现以下几种矩阵变换:
- 左右反转
- 上下反转
- 90度顺时针旋转(矩阵转置 + 左右反转)
- 180度顺时针旋转(左右反转 + 上下反转)
- 270度顺时针旋转(矩阵转置 + 上下反转)
虽然涉及的操作看起来较多,但只需掌握左右反转、上下反转和矩阵转置这三个基础操作,即可组合实现其他所有的矩阵变换。
另外,正文关于反转方式的后面标注了通用或者仅方阵适用的标签 ; 通用意思是方阵和非方阵都适用;仅方阵适用意思是,仅行列数相等可用。
一、 基础操作代码实现
1. 左右反转(通用)
左右反转指的是将矩阵的每一行进行左右对称交换。
public static void leftRight(int[][] m){
int row = m.length;
int col = m[0].length;
for(int i = 0; i < row; i++){
for(int j = 0; j < col / 2; j++){
int temp = m[i][j];
m[i][j] = m[i][col - 1 - j];
m[i][col - 1 - j] = temp;
}
}
}
示例验证
输入矩阵:
1 2 3
4 5 6
7 8 9
左右反转后的矩阵:
3 2 1
6 5 4
9 8 7
2. 上下反转(通用)
上下反转是将矩阵的每一列进行上下对称交换。
public static void upDown(int[][] m){
int row = m.length;
int col = m[0].length;
for(int i = 0; i < row / 2; i++){
for(int j = 0; j < col; j++){
int temp = m[i][j];
m[i][j] = m[row - 1 - i][j];
m[row - 1 - i][j] = temp;
}
}
}
示例验证
输入矩阵:
1 2 3
4 5 6
7 8 9
上下反转后的矩阵:
7 8 9
4 5 6
1 2 3
3. 矩阵转置
方法一(通用):
矩阵转置是将矩阵的行与列进行互换,适用于方阵和非方阵。
//矩阵转置 通用
public static int[][] tran(int[][] m){
int row=m.length;
int col=m[0].length;
int[][] ret=new int[col][row];
for(int i=0;i<col;i++){
for(int j=0;j<row;j++){
ret[i][j]=m[j][i];
}
}
return ret;//ret数组是转置后的数组
}
方法二(仅方阵适用):
public static void tranN(int[][] m){
int n=m.length;
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){//注意j从i开始
int temp=m[i][j];
m[i][j]=m[j][i];
m[j][i]=temp;
}
}
}
示例验证
示例1:方阵
输入矩阵:
1 2 3
4 5 6
7 8 9
转置后的矩阵:
1 4 7
2 5 8
3 6 9
示例2:非方阵
输入矩阵(2行3列):
1 2 3
4 5 6
转置后的矩阵:
1 4
2 5
3 6
二、组合操作实现复杂变换
4. 90度顺时针旋转
方法一(通用):
通过创建一个新的矩阵,将原矩阵的元素按90度顺时针旋转后赋值到新矩阵中。
public static int[][] r90(int[][] m){
int row = m.length;
int col = m[0].length;
int[][] ret = new int[col][row];
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
ret[j][row - 1 - i] = m[i][j];
}
}
return ret;
}
示例验证
输入矩阵:
1 2 3
4 5 6
7 8 9
90度顺时针旋转后的矩阵:
7 4 1
8 5 2
9 6 3
方法二(仅适用于方阵):
通过转置后左右反转实现90度旋转。
public static void r90n(int[][] m){
int n = m.length;
// 转置
for(int i = 0; i < n; i++){
for(int j = i; j < n; j++){
int temp = m[i][j];
m[i][j] = m[j][i];
m[j][i] = temp;
}
}
// 左右反转
for(int i = 0; i < n; i++){
for(int j = 0; j < n / 2; j++){
int temp = m[i][j];
m[i][j] = m[i][n - 1 - j];
m[i][n - 1 - j] = temp;
}
}
}
示例验证
输入矩阵:
1 2 3
4 5 6
7 8 9
90度顺时针旋转后的矩阵:
7 4 1
8 5 2
9 6 3
5. 180度顺时针旋转(通用)
通过左右反转和上下反转的组合实现180度旋转。
public static void r180(int[][] m){
int row = m.length;
int col = m[0].length;
// 左右反转
for(int i = 0; i < row; i++){
for(int j = 0; j < col / 2; j++){
int temp = m[i][j];
m[i][j] = m[i][col - 1 - j];
m[i][col - 1 - j] = temp;
}
}
// 上下反转
for(int i = 0; i < row / 2; i++){
for(int j = 0; j < col; j++){
int temp = m[i][j];
m[i][j] = m[row - 1 - i][j];
m[row - 1 - i][j] = temp;
}
}
}
示例验证
输入矩阵:
1 2 3
4 5 6
7 8 9
180度顺时针旋转后的矩阵:
9 8 7
6 5 4
3 2 1
另一个示例:非方阵
输入矩阵(2行3列):
1 2 3
4 5 6
180度顺时针旋转后的矩阵:
6 5 4
3 2 1
6. 270度顺时针旋转
方法一(通用):
public static int[][] r270(int[][] m){
int row = m.length;
int col = m[0].length;
int[][] ret = new int[col][row]; // 行列相反
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
ret[col - 1 - j][i] = m[i][j];
}
}
return ret; // 必须返回新的数组,因为如果行列不相等,那么旋转270度后的矩阵形状是不同的
}
示例验证
输入矩阵(2行3列):
1 2 3
4 5 6
270度顺时针旋转后的矩阵(3行2列):
3 6
2 5
1 4
方法二(仅适用于方阵):
通过转置后上下反转实现270度旋转。
public static void r270n(int[][] m){
int n = m.length;
// 转置
for(int i = 0; i < n; i++){
for(int j = i; j < n; j++){
int temp = m[i][j];
m[i][j] = m[j][i];
m[j][i] = temp;
}
}
// 上下反转
for(int i = 0; i < n / 2; i++){
for(int j = 0; j < n; j++){
int temp = m[i][j];
m[i][j] = m[n - 1 - i][j];
m[n - 1 - i][j] = temp;
}
}
}
示例验证
输入矩阵:
1 2 3
4 5 6
7 8 9
270度顺时针旋转后的矩阵:
3 6 9
2 5 8
1 4 7
总结
通过以上代码模板,我们可以轻松实现矩阵的各种翻转与旋转操作。掌握左右反转、上下反转和矩阵转置这三个基础操作后,其他复杂的矩阵变换都可以通过组合这些操作来实现。