题目描述:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如,输入以下矩阵:
1 2 3 4 5
6 7 8 9 0
1 2 3 4 5
6 7 8 9 0
1 2 3 4 5
则打印出:1, 2, 3, 4, 5, 0, 5, 0, 5, 4, 3, 2, 1, 6, 1, 6, 7, 8, 9, 4, 9, 8, 7, 2, 3
解题思路:
- 将复杂的问题分解成若干个简单的问题
循环每次打印矩阵的一圈
第一圈的左上角坐标为(0,0),
第二圈的左上角坐标为(1,1),
第三圈的左上角坐标为(2,2),
。。。。。。。。。。。依次类推左上角的行rows坐标和列columns坐标总是相同的,所在矩阵中选取左上角为(start, start)一圈作为分析的目标。
- 对于5*5的矩阵而言,最后一圈只有一个数字,对应的坐标为(2,2),可以发现5>2*2; 对于6*6的矩阵而言。最后一圈有4个数字,左上角坐标依然为(2*2), 而6>2*2。由此可得出,
让循环继续的条件是:rows > startX x 2并且columns > startY x 2。
由此可以得出循环打印矩阵函数:
//顺时针循环打印
void PrintMatrixClockWisely(int arr[][5], int rows, int columns){
if(arr == NULL || rows <= 0 || columns <=0)
return;
int start = 0;
while(rows > start * 2 && columns > start * 2){
PrintMatrixInCircle(arr, rows, columns, start);
++start;
}
}
将打印一个矩阵(复杂问题)分解为分别打印一圈(简单问题):
- 从左到右打印一行
- 从上到下打印一列
- 从右到左打印一行
- 从下到上打印一列
每一步我们根据起始坐标和终止坐标用一个循环就能打印出一列或者一行。
最后一圈可能退化成只有一行,甚至只有一个数字,因此打印这样的一圈就需要四步,也可能是三、二或只有一步。
- 如果只有一行,就不需要第二步了。即前提条件是终止行号大于起始行号。
- 需要第三步打印的条件是圈内至少有两行两列,即除了要求终止行号大于起始行号外,还要求终止列号大于起始列号。
- 打印第四步的前提条件是至少有三行两列,因此要求终止行号比起始行号至少大2,同时终止列号大于起始列号。
打印一圈函数实现:
//打印一圈
void PrintMatrixInCircle(int arr[][5], int rows, int columns, int start){
//终止行
int endX = rows - 1 - start;
//终止列
int endY = columns - 1 - start;
//从左到右打印一行
for(int i = start; i <= endX; ++i)
std::cout << arr[start][i] << " ";
//从上到下打印一列
if(start < endY){//终止列大于起始行
for(int i = start + 1; i <= endY; ++i)
std::cout << arr[i][endX] << " ";
}
//从右到左打印一行
if(start < endX && start < endY){
for(int i = endX - 1; i >= start; --i)
std::cout << arr[endY][i] << " ";
}
//从下到上打印一列
if(start < endX && start < endY - 1)
for(int i = endY - 1; i >= start + 1; --i)
std::cout << arr[i][start] << " ";
}
测试用例:
int main(){
//测试矩阵
int arr[5][5] = {
1, 2, 3, 4, 5,
6, 7, 8, 9, 0,
1, 2, 3, 4, 5,
6, 7, 8, 9, 0,
1, 2, 3, 4, 5
};
//顺序打印矩阵
for(auto i = 0; i < 5; ++i)
for(auto j = 0; j < 5; ++j)
std::cout << arr[i][j] << " "; //Output:1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
std::cout << std::endl;
//顺时针打印矩阵
PrintMatrixClockWisely(arr, 5, 5); //Output: 1, 2, 3, 4, 5, 0, 5, 0, 5, 4, 3, 2, 1, 6, 1, 6, 7, 8, 9, 4, 9, 8, 7, 2, 3
return 0;
}