每日一题(32) - 顺时针打印矩阵 和 螺旋矩阵

来源:互联网 发布:移动网络改成电信 编辑:程序博客网 时间:2024/04/28 13:52

题目来自剑指offer

题目:



思路:每次打印一个环


根据上图,打印环时,可以分为四步:

(1)打印1,只要环存在,就该行就可以打印。

(2)打印2,只要环有多行(有待打印的元素)时,才可以打印。

(3)打印3、当环有多行(和其一次行区分开)+有多列(有待打印的元素)时,才有可能打印该行

(4)打印4、当环有多列(和其一次列区分开)+有多行(有待打印的元素)时才有可能打印该列

注意:对于 判断是否有待打印的元素 的条件,可以再for循环中包含,可以在if中少写一个判断。

代码:

#include <iostream>#include <iomanip>#include <assert.h>using namespace std;/*函数功能:打印环nStart:起点坐标(nStart,nStart)nEndRows:本次打印的最后一行nEndCols:本次打印的最后一列*/void PrintCircle(int** pArr,int nStart,int nEndRows,int nEndCols){//从左到右打印一行//打印条件:第一行肯定能打印,不用写if语句//打印第nStart行,列区间由nStart到nColsfor (int nCurCol = nStart;nCurCol <= nEndCols;nCurCol++){cout<<pArr[nStart][nCurCol]<<" ";}//从上到下打印一列//打印条件:终止行大于第起始行(此条件已经暗含在for循环中了,可以不写)//打印第nCols列,列区间由nStart + 1到nRowsfor (int nCurRow = nStart + 1;nCurRow <= nEndRows;nCurRow++){cout<<pArr[nCurRow][nEndCols]<<" ";}//从右到左打印一行//打印条件:待打印的环中的行必须超过两行 且 列超过两列//满足条件:nEndCols > nStart : 要求被打印那一行必须有未打印的元素(此条件已经暗含在for循环中了,可以不写)//满足条件:nEndRows > nStart : 这是要和前一次打印的行区分开。//打印第nRows行,列区间由nCols - 1到nStartif (nEndRows > nStart){for (int nCurCol = nEndCols - 1;nCurCol >= nStart;nCurCol--){cout<<pArr[nEndRows][nCurCol]<<" ";}}//从下到上打印一列//打印条件:待打印的环中的行必须超过三行 且 列超过两列//满足条件:nEndCols > nStart : 因为这是要和前一次打印的列区分开。//满足条件:nEndRows > nStart : 要求被打印那一列必须有未打印的元素,(此条件已经暗含在for循环中了,可以不写)。//打印第nStart列,行区间由nRows - 1到nStart + 1if (nEndCols > nStart) {for (int nCurRow = nEndRows - 1;nCurRow >= nStart + 1;nCurRow--){cout<<pArr[nCurRow][nStart]<<" ";}}}/*函数功能:确定环的个数nRows:表示总行数,nCols:表示总列数*/void PrintMatrix(int** pArr,int nRows,int nCols){assert(pArr && nCols > 0 && nRows > 0);int nStart = 0;while (2 * nStart < nRows && 2 * nStart < nCols){PrintCircle(pArr,nStart,nRows - 1 - nStart,nCols - 1 - nStart);nStart++;}}int main(){int nRows = -1;int nCols = -1;int num = 1;cin>>nRows>>nCols;int** pArr = new int*[nRows];for(int i = 0;i < nRows;i++){pArr[i]= new int[nCols];for(int j = 0;j < nCols;j++){pArr[i][j]= num++;cout<<setw(3)<<pArr[i][j]<<" ";}cout<<endl;}cout<<endl;PrintMatrix(pArr,nRows,nCols);cout<<endl;system("pause");return 1;

题目扩展

题目:产生螺旋数组

举例:


思路:与上面的思路是一样的,代码也几乎一样。

代码:

#include <iostream>#include <iomanip>#include <assert.h>using namespace std;/*函数功能:打印环nStart:起点坐标(nStart,nStart)nEndRows:本次打印的最后一行nEndCols:本次打印的最后一列*/void PrintCircle(int** pArr,int nStart,int nEndRows,int nEndCols,int& nCnt){//从左到右打印一行//打印条件:第一行肯定能打印,不用写if语句//打印第nStart行,列区间由nStart到nColsfor (int nCurCol = nStart;nCurCol <= nEndCols;nCurCol++){pArr[nStart][nCurCol] = nCnt++;}//从上到下打印一列//打印条件:终止行大于第起始行(此条件已经暗含在for循环中了,可以不写)//打印第nCols列,列区间由nStart + 1到nRowsfor (int nCurRow = nStart + 1;nCurRow <= nEndRows;nCurRow++){pArr[nCurRow][nEndCols]= nCnt++;}//从右到左打印一行//打印条件:待打印的环中的行必须超过两行 且 列超过两列//满足条件:nEndCols > nStart : 要求被打印那一行必须有未打印的元素(此条件已经暗含在for循环中了,可以不写)//满足条件:nEndRows > nStart : 这是要和前一次打印的行区分开。//打印第nRows行,列区间由nCols - 1到nStartif (nEndRows > nStart){for (int nCurCol = nEndCols - 1;nCurCol >= nStart;nCurCol--){pArr[nEndRows][nCurCol]= nCnt++;}}//从下到上打印一列//打印条件:待打印的环中的行必须超过三行 且 列超过两列//满足条件:nEndCols > nStart : 因为这是要和前一次打印的列区分开。//满足条件:nEndRows > nStart : 要求被打印那一列必须有未打印的元素,(此条件已经暗含在for循环中了,可以不写)。//打印第nStart列,行区间由nRows - 1到nStart + 1if (nEndCols > nStart) {for (int nCurRow = nEndRows - 1;nCurRow >= nStart + 1;nCurRow--){pArr[nCurRow][nStart]= nCnt++;}}}/*函数功能:确定环的个数nRows:表示总函数,nCols:表示总列数*/void PrintMatrix(int** pArr,int nRows,int nCols){assert(pArr && nCols > 0 && nRows > 0);int nStart = 0;int nCnt = 1;while (2 * nStart < nRows && 2 * nStart < nCols){PrintCircle(pArr,nStart,nRows - 1 - nStart,nCols - 1 - nStart,nCnt);nStart++;}}int main(){int nRows = -1;int nCols = -1;int num = 1;cin>>nRows>>nCols;//产生二维数组int** pArr = new int*[nRows];for(int i = 0;i < nRows;i++){pArr[i]= new int[nCols];}//打印PrintMatrix(pArr,nRows,nCols);//输出for(int i = 0;i < nRows;i++){for(int j = 0;j < nCols;j++){cout<<setw(3)<<pArr[i][j]<<" ";}cout<<endl;}system("pause");return 1;}





原创粉丝点击