题目和要求看下面的说明
/*
题目描述:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
输入:
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行包括两个整数m和n(1<=m,n<=1000):表示矩阵的维数为m行n列。
接下来的m行,每行包括n个整数,表示矩阵的元素,其中每个元素a的取值范围为(1<=a<=10000)。
输出:
对应每个测试案例,输出一行,
按照从外向里以顺时针的顺序依次打印出每一个数字,每个数字后面都有一个空格。
样例输入:
4 4
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
样例输出:
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
*/
#include<stdio.h>
#include<stdlib.h>
//根据起点来按圈打印矩阵
void printMatrixByCircle(int **arr,int m,int n,int begin){
if(arr==NULL||m<=0||n<=0||begin<0){
return;
}
//先从起点开始向右打印
for(int i=begin;i<n-begin;i++){//边界为 n-begin
printf("%d ",arr[begin][i]);//行固定,arr[bigin][i]也可以这样写:*(*(arr+begin)+i)
}
//然后向下打印
for(int i=begin+1;i<m-begin;i++){//为避免重复打印,起点为begin+1;边界为:m-begin
printf("%d ",arr[i][n-begin-1]);//列固定
}
//然后向左打印;这里如果 循环中i>=begin这样写,则当我们输入3*4的矩阵时,则为把起点元素打印两次 。因此应该这样来改写:i>begin ,把i=begin的情况留给下面那一组
for(int i=n-begin-2;i>begin;i--){//为避免重复打印,起点为n-begin-2;终点边界为 begin
printf("%d ",arr[m-begin-1][i]);
}
//然后向上打印
for(int i=m-1-begin;i>begin;i--){//为避免重复打印,起点为m-begin-2;终点边界为 begin+1
printf("%d ",arr[i][begin]);
}
}
void printMatrixByClockwise(int **arr,int m,int n){
if(arr==NULL||m<=0||n<=0){
return;
}
int begin=0;//第一步是从左上角位置为起点的圆开始打印
while(m>2*begin&&n>2*begin){//只有当m、n都大于begin的两倍时,才会有圈出现
printMatrixByCircle(arr,m,n,begin);
begin++;
}
}
int main(void){
int m,n;
while(scanf("%d%d",&m,&n)!=EOF){
if(m>0&&n>0){
int **arr;
arr=(int **)malloc(m*sizeof(int *));
if(arr==NULL){
exit(EXIT_FAILURE);
}
int val;
for(int i=0;i<m;i++){
arr[i]=(int *)malloc(n*sizeof(int));
if(arr[i]==NULL){
exit(EXIT_FAILURE);
}
for(int j=0;j<n;j++){
scanf("%d",&val);
arr[i][j]=val;
}
}
printMatrixByClockwise(arr,m,n);
}
}
return 0;
}
上面编码的思路就是利用4个for循环对一个圈进行了打印。
在调试过程中,遇到了如下的问题:能够处理4*3和4*4这样的矩阵,但是在输入为3*4的矩阵时,本来应该不会执行向左打印,但是向左打印的代码中for(int i=n-begin-2;i>=begin;i--)
是要被执行的。
即会将arr[1][1]
的元素重复打印。
因此我们将如下代码中的两个for循环条件进行了变化。
for(int i=n-begin-2;i>=begin;i--){//为避免重复打印,起点为n-begin-2;终点边界为 begin
printf("%d ",arr[m-begin-1][i]);
}
//然后向上打印
for(int i=m-2-begin;i>begin;i--){//为避免重复打印,起点为m-begin-2;终点边界为 begin+1
printf("%d ",arr[i][begin]);
}
变化的结果如下:
//然后向左打印;这里如果 循环中i>=begin这样写,则当我们输入3*4的矩阵时,则为把起点元素打印两次 。因此应该这样来改写:i>begin ,把i=begin的情况留给下面那一组
for(int i=n-begin-2;i>begin;i--){//为避免重复打印,起点为n-begin-2;终点边界为 begin
printf("%d ",arr[m-begin-1][i]);
}
//然后向上打印
for(int i=m-1-begin;i>begin;i--){//为避免重复打印,起点为m-begin-2;终点边界为 begin+1
printf("%d ",arr[i][begin]);
}
这样就能够将 类似3*4的矩阵正常打印了,但是这样改了之后当测试4*3的矩阵时,发现又有重复的元素被打印了。
在类似4*3的矩阵中,按圈打印时的第二圈中,应该只会执行向右打印和向下打印,但是代码中向上打印被执行了。向上打印中for循环条件如下:
for(int i=m-1-begin;i>begin;i--)
这样就导致了a[2][1]的元素被打印出来了。
总结:向以上的问题就是代码不能够同时处理3*4和4*3这样的矩阵。因此我们在代码中加入一个判断语句即可解决以上两个问题的冲突。
完整代码如下:
/*
题目描述:
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
输入:
输入可能包含多个测试样例,对于每个测试案例,
输入的第一行包括两个整数m和n(1<=m,n<=1000):表示矩阵的维数为m行n列。
接下来的m行,每行包括n个整数,表示矩阵的元素,其中每个元素a的取值范围为(1<=a<=10000)。
输出:
对应每个测试案例,输出一行,
按照从外向里以顺时针的顺序依次打印出每一个数字,每个数字后面都有一个空格。
样例输入:
4 4
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
样例输出:
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
*/
#include<stdio.h>
#include<stdlib.h>
//根据起点来按圈打印矩阵
void printMatrixByCircle(int **arr,int m,int n,int begin){
if(arr==NULL||m<=0||n<=0||begin<0){
return;
}
//先从起点开始向右打印
for(int i=begin;i<n-begin;i++){//边界为 n-begin
printf("%d ",arr[begin][i]);//行固定,arr[bigin][i]也可以这样写:*(*(arr+begin)+i)
}
//然后向下打印
for(int i=begin+1;i<m-begin;i++){//为避免重复打印,起点为begin+1;边界为:m-begin
printf("%d ",arr[i][n-begin-1]);//列固定
}
//然后向左打印;这里如果 循环中i>=begin这样写,则当我们输入3*4的矩阵时,则为把起点元素打印两次 。因此应该这样来改写:i>begin ,把i=begin的情况留给下面那一组
if(m>=n){
for(int i=n-begin-2;i>=begin;i--){//为避免重复打印,起点为n-begin-2;终点边界为 begin
printf("%d ",arr[m-begin-1][i]);
}
//然后向上打印
//当输入4*3的矩阵时,会将a[2][1] 的元素重复打印
for(int i=m-2-begin;i>begin;i--){//为避免重复打印,起点为m-begin-2;终点边界为 begin+1
printf("%d ",arr[i][begin]);
}
}
if(m<n) {
for(int i=n-begin-2;i>begin;i--){//为避免重复打印,起点为n-begin-2;终点边界为 begin
printf("%d ",arr[m-begin-1][i]);
}
//然后向上打印
//当输入4*3的矩阵时,会将a[2][1] 的元素重复打印
for(int i=m-1-begin;i>begin;i--){//为避免重复打印,起点为m-begin-2;终点边界为 begin+1
printf("%d ",arr[i][begin]);
}
}
}
void printMatrixByClockwise(int **arr,int m,int n){
if(arr==NULL||m<=0||n<=0){
return;
}
int begin=0;//第一步是从左上角位置为起点的圆开始打印
while(m>2*begin&&n>2*begin){//只有当m、n都大于begin的两倍时,才会有圈出现
printMatrixByCircle(arr,m,n,begin);
begin++;
}
}
int main(void){
int m,n;
while(scanf("%d%d",&m,&n)!=EOF){
if(m>0&&n>0){
int **arr;
arr=(int **)malloc(m*sizeof(int *));
if(arr==NULL){
exit(EXIT_FAILURE);
}
int val;
for(int i=0;i<m;i++){
arr[i]=(int *)malloc(n*sizeof(int));
if(arr[i]==NULL){
exit(EXIT_FAILURE);
}
for(int j=0;j<n;j++){
scanf("%d",&val);
arr[i][j]=val;
}
}
printMatrixByClockwise(arr,m,n);
}
}
return 0;
}