Java通过继承实现矩阵顺/逆时针多次旋转 逆时针功能异常排查
矩阵逆时针旋转问题修复说明
本次排查出3个核心问题,修复后可正常运行:
问题1:二维数组浅拷贝导致输入污染
主函数中使用System.arraycopy拷贝二维数组属于浅拷贝,matrix1和matrix2的行引用指向同一块内存,顺时针旋转修改matrix1时,matrix2的内容会同步变更,导致逆时针旋转的输入不是原始矩阵。
修复方案:改为逐行深拷贝二维数组。
问题2:非方阵场景下逆时针打印逻辑错误
Anticlockwise类的rotation方法打印矩阵时,列数错误使用了行数mat2.length,如果矩阵行数≠列数,会出现打印内容缺失或数组越界异常。
修复方案:列数改为取当前行的长度mat2[i].length。
问题3:基类设计不符合继承要求
需求明确要求通过继承实现功能,原基类Clock为空类,未定义子类必须实现的方法规范,不符合面向对象设计要求。
修复方案:将Clock改为抽象类,定义子类必须实现的rotate和rotation抽象方法。
修复后完整代码
import java.util.*; abstract class Clock { abstract int[][] rotate(); abstract void rotation(); } class Clockwise extends Clock { int[][] mat1; int m, n, r; Clockwise(int m, int n, int r, int[][] mat1input) { this.m = m; this.n = n; this.r = r; // 构造时直接深拷贝输入,避免外部修改影响内部逻辑 this.mat1 = new int[m][n]; for (int i = 0; i < m; i++) { this.mat1[i] = Arrays.copyOf(mat1input[i], n); } } @Override void rotation() { while (r > 0) { mat1 = rotate(m, n, mat1); r -= 1; } System.out.println("Clockwise"); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) System.out.print(mat1[i][j] + " "); System.out.print("\n"); } } int[][] rotate(int m, int n, int mat[][]) { int row = 0, col = 0; int prev, curr; while (row < m && col < n) { if (row + 1 == m || col + 1 == n) break; prev = mat[row + 1][col]; for (int i = col; i < n; i++) { curr = mat[row][i]; mat[row][i] = prev; prev = curr; } row++; for (int i = row; i < m; i++) { curr = mat[i][n - 1]; mat[i][n - 1] = prev; prev = curr; } n--; if (row < m) { for (int i = n - 1; i >= col; i--) { curr = mat[m - 1][i]; mat[m - 1][i] = prev; prev = curr; } } m--; if (col < n) { for (int i = m - 1; i >= row; i--) { curr = mat[i][col]; mat[i][col] = prev; prev = curr; } } col++; } return mat; } // 实现抽象方法要求 @Override int[][] rotate() { return rotate(m, n, mat1); } } class Anticlockwise extends Clock { int[][] mat2; int r; int top, left; int bottom, right; int prev, curr; Anticlockwise(int[][] mat2input, int r) { this.r = r; // 构造时深拷贝输入 int m = mat2input.length; int n = mat2input[0].length; this.mat2 = new int[m][n]; for (int i = 0; i < m; i++) { this.mat2[i] = Arrays.copyOf(mat2input[i], n); } } @Override void rotation() { mat2 = rotate(); System.out.println("Anti clockwise"); for (int i = 0; i < mat2.length; i++) { // 修复列数获取错误问题 for (int j = 0; j < mat2[i].length; j++) System.out.print(mat2[i][j] + " "); System.out.print("\n"); } } @Override int[][] rotate() { for (int z = 0; z < r; z++) { top = 0; left = 0; this.bottom = mat2.length - 1; this.right = mat2[0].length - 1; while (left < right && top < bottom) { prev = mat2[top + 1][right]; for (int i = right; i > left - 1; i--) { curr = mat2[top][i]; mat2[top][i] = prev; prev = curr; } top += 1; for (int i = top; i < bottom + 1; i++) { curr = mat2[i][left]; mat2[i][left] = prev; prev = curr; } left += 1; for (int i = left; i < right + 1; i++) { curr = mat2[bottom][i]; mat2[bottom][i] = prev; prev = curr; } bottom -= 1; for (int i = bottom; i > top - 1; i--) { curr = mat2[i][right]; mat2[i][right] = prev; prev = curr; } right -= 1; } } return mat2; } } public class MatrixRotation { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int m = sc.nextInt(); int n = sc.nextInt(); int[][] matrix = new int[m][n]; sc.nextLine(); for (int i = 0; i < m; i++) { String[] line = sc.nextLine().trim().split(" "); for (int j = 0; j < n; j++) { matrix[i][j] = Integer.parseInt(line[j]); } } int r = sc.nextInt(); sc.close(); // 两个子类各自拷贝输入,不需要外部提前拷贝 Clockwise clockwise = new Clockwise(m, n, r, matrix); Anticlockwise anticlockwise = new Anticlockwise(matrix, r); clockwise.rotation(); anticlockwise.rotation(); } }
内容的提问来源于stack exchange,提问作者vennelaganti venkata lakshmi S
相关产品推荐
相关产品推荐

