《剑指offer》面试题:顺时针打印矩阵
来源:互联网 发布:2017网络上很火的神曲 编辑:程序博客网 时间:2024/04/30 15:06
题目和要求看下面的说明
/*题目描述:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:1 2 3 45 6 7 89 10 11 1213 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 41 2 3 45 6 7 89 10 11 1213 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 45 6 7 89 10 11 1213 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 41 2 3 45 6 7 89 10 11 1213 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;}
0 0
- 《剑指offer》面试题:顺时针打印矩阵
- 剑指offer面试题 顺时针打印矩阵
- 剑指offer面试题20顺时针打印矩阵
- [剑指offer][面试题20]顺时针打印矩阵
- 剑指offer 面试题20:顺时针打印矩阵
- 《剑指offer》面试题20顺时针打印矩阵
- 【剑指offer】面试题20:顺时针打印矩阵
- 剑指offer 面试题20 顺时针打印矩阵
- 剑指Offer:面试题20 顺时针打印矩阵
- 《剑指Offer》面试题20:顺时针打印矩阵
- 剑指offer 面试题20—顺时针打印矩阵
- 《剑指Offer》学习笔记--面试题20:顺时针打印矩阵
- 剑指offer--面试题20:顺时针打印矩阵--Java实现
- 【剑指Offer学习】【面试题20 : 顺时针打印矩阵】
- 【剑指Offer面试题】 九度OJ1391:顺时针打印矩阵
- 剑指offer面试题20-顺时针打印矩阵
- 剑指offer-面试题20:顺时针打印矩阵
- 剑指offer-面试题20.顺时针打印矩阵
- iOS-新浪微博开发-26-下拉刷新
- 类方法
- 指针的指针
- 【软考】软考视频总结
- 行业门户网站、论坛的微信内容运营策划
- 《剑指offer》面试题:顺时针打印矩阵
- Android 使用Mob移动开发SDK笔记
- c# font gdicharset
- ARQ与滑动窗口
- arm汇编实验-arm指令集的应用
- 转发和重定向
- KVC 键值编码与KVO键值监听的应用(二)——路径的使用和一对多关系的应用
- java实现多继承
- 23设计模式之桥接模式(Bridge)