題目描述
給一個m*n矩陣,請以“之"字型進行遍歷輸出,
{ {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16} }輸出結果爲:1 2 5 9 6 3 4 7 10 13 14 11 8 12 15 16
{ {1,2,3,4}, {5,6,7,8}, {9,10,11,12} }
輸出:1 2 5 9 6 3 4 7 10 11 8 12
分析
該題目跟我博客裏的其他兩篇關於矩陣的操作的思路很相似,大家感興趣的可以參看這兩篇進行對比查看:
做該題不能死扣每個點與下一個點之間的關係,這樣就是陷入出力不討好的怪圈中,應該從更高的層面去考慮,可以參考矩陣的旋轉和矩陣的旋轉打印那樣的方法。當我們在遍歷矩陣的時候發現,我們每次輸出的數都是斜着的一行(左下方到右上方),所以我們每次可以將問題分解爲,每次遍歷一個斜行,至於方向是從左下到↗️右上,還是右上到↙️左下,我們可以使用一個bool類型的數據來記錄,每次把這一個斜行輸出完畢之後,就更換一下這個bool類型的數據即可。
在動手code之前,我們將解決方案分爲兩個函數,第一個函數將整個矩陣劃分爲(m+n-1)個斜行,我們只需要記錄這一斜行的兩端的座標(ax,ay)(bx,by)即可。再定義一個函數進行輸出某一斜行的數據,其中傳進去的bool值可以讓它知道什麼方向輸出。
廢話少數,show codes:
#include<iostream>
#include<vector>
using namespace std;
//輸出斜線(ax,ay)到(bx,by)的一列內容,根據flag來確定輸出打印的方向
void printLine(vector<vector<int>>matrix,int ax,int ay,int bx,int by,bool flag){
//cout<<"("<<ax<<","<<ay<<"),("<<bx<<","<<by<<")"<<endl;
if(flag){
//從左下方往右上方移動(bx,by)->(ax,ay)
while( bx >= ax){
printf("%d ",matrix[bx][by]);
bx--;
by++;
}
}else{
//從右上往左下移動
while(ay >= by){
printf("%d ",matrix[ax][ay]);
ax++;
ay--;
}
}
}
void printMatrixZig(vector<vector<int>>matrix){
int m = matrix.size();
int n = matrix[0].size();
bool up2Down = true;
int ax=0;
int ay=0;
int bx=0;
int by=0;
for(int i=0;i<m+n-1;i++)
{
printLine(matrix,ax,ay,bx,by,up2Down);
if(i<m-1){
bx++;
}else{
by++;
}
if(i<n-1){
ay++;
}else{
ay=n-1;
ax++;
}
up2Down = !up2Down;
}
}
int main()
{
vector<vector<int>>matrix={
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
printMatrixZig(matrix);
return 0;
}