题目:
输入一个矩阵,按照从外圈向内圈顺时针打印数组元素。例如输入二维数组 a[3][3] = {{1,3,4}, {5,6,7}, {8,2,0}},打印出来的结果应该是:1 3 4 7 0 2 8 5 6
解决思路:
(1)首先,本文实现的顺时针打印,起始位置是矩阵的左上角,即数组的 【0】【0】位置;
(2)一个圈顺时针打印一遍,要分四个方向打印:从左到右、从上到下、从右到左、从下到上;
(3)每一个方向打印完,要有结束位置,且不能有重复位置的打印,比如当前列最大值为3,从左到右打印到【0】【2】时,这个方向已经打印结束。接下来是从上到下的方向,但此时【0】【2】已经打印过了,所以行值要加1,即从【1】【2】开始打印。类似这样,每个方向都要注意这一点;
(4)一圈打印完,去到第二个圈的起始位置时,我们分析发现:当前圈的起始位置就是上一个圈的起始位置的行列都加1;
(5)同时,一圈打印结束,我们当前最外圈的元素已经输出了。为避免重复,我们下一圈的起始位置可以限制下一圈的从右到左和从下向上方向的结束条件;那我们的行值需要减1,列值需要减1,即得到当前圈行、列值得最大值,以此控制另外两个方向的结束条件。
实现代码:
#include
#include
#define ROW 4
#define COL 4
void _Print(int a[ROW][COL], size_t r, size_t c, size_t row, size_t col)
{//传入的第二、三个参数表示当前顺时针圈的起始位置
//传入的第四、五的参数为当前圈的行、列的最大值
size_t i = r;
size_t j = c;
//1.从左向右打
for (; j < col; ++j)
{
printf("%d ", a[i][j]);
}
//2.从上向下打
j--;//上个循环结束在j = col
for (i++; i < row; ++i)//i++避免重复打印
{
printf("%d ", a[i][j]);
}
//3.从右向左打
i--;//上个循环结束在i = row
for (j--; j > c; --j)//j--避免重复打印
{
printf("%d ", a[i][j]);
}
//4.从下向上打
//上个循环在j = c(起始位置的列)
for (; i > r; --i)//上个循环j=c未打印,所以这里不用i++避免重复打印
{
printf("%d ", a[i][j]);
}
}
void Print(int a[ROW][COL], size_t row, size_t col)
{
size_t i = 0;
size_t j = 0;
while (i < row && j < col)
{
_Print(a, i, j,row, col);
i++;
j++;//每圈打印完,起始位置i,j都要++
row--;
col--;//每圈打完,当前矩阵行、列的最大值也要减1
}
printf("\n");
}
int main()
{
int a[ROW][COL] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
Print(a, ROW, COL);
system("pause");
return 0;
}