题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
分析:
- 循环结束的条件。第一圈左上角为(0,0),第二圈左上角为(1,1),左上角的行列坐标相同,于是我们可以在矩阵中选取左上角为(start,start)的一圈作为分析的目标。
- 循环继续的条件。对于5 * 5矩阵,最后一圈只有一个数字,坐标为(2,2),且5 > 2 * 2;对于6 * 6矩阵,最后一圈有4个数字,左上角为(2,2),且6 > 2 * 2仍成立。总结出循环继续的条件是columns > startX * 2 && rows > startY * 2。(有点难发现…)
- 如何打印一圈。打印一圈可以分四步:第一步,左右,第二步,上下,第三步,右左,第四步,下上。每一步根据起始坐标和终止坐标用一个循环打印。值得注意的是,最后一圈有可能退化成只有一行甚至只有一个数字,因此需要分析打印每一步的前提条件:第一步,必须,第二步,终止行号>起始行号,第三步,除了要求终止行号>起始行号&&终止列号>起始列号,第四步,终止行号-起始行号>2&&终止列号>起始列号。
public class PrintMatrix {
/**
* 顺时针打印数组
* @param numbers二维数组
* @param rows 行数
* @param columns列数
*/
public void printMatrixClockwisely(int[][] numbers, int rows, int columns) {
if (numbers == null || rows <= 0 || columns <= 0) {
return;
}
int start = 0;
while (start * 2 < columns && start * 2 < rows) { //打印循环条件
printMatrixInCircle(numbers, rows, columns, start);
start++;
}
}
public void printMatrixInCircle(int[][] numbers, int rows, int columns,int start) {
//终止列号
int endX = columns - 1 - start;
//终止行号
int endY = rows - 1 - start;
//从左至右打印一行
for(int i = start; i <= endX; i++){
System.out.print(numbers[start][i]+" ");
}
//从上到下打印一列
if(endY > start){
for(int i = start+1; i<= endY; i++){
System.out.print(numbers[i][endX] + " ");
}
}
//从右至左打印一行
if(endY > start && endX > start){
for(int i = endX-1 ; i>= start; i--){
System.out.print(numbers[endY][i] + " ");
}
}
//从下到上打印一列
if(endY - 1 > start && endX > start){
for(int i = endY-1; i >= start+1 ; i--){
System.out.print(numbers[i][start] + " ");
}
}
}
}