矩陣的“之"字遍歷ZigZag打印

題目描述

給一個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

分析

該題目跟我博客裏的其他兩篇關於矩陣的操作的思路很相似,大家感興趣的可以參看這兩篇進行對比查看:

矩陣順時針旋轉90度

做該題不能死扣每個點與下一個點之間的關係,這樣就是陷入出力不討好的怪圈中,應該從更高的層面去考慮,可以參考矩陣的旋轉和矩陣的旋轉打印那樣的方法。當我們在遍歷矩陣的時候發現,我們每次輸出的數都是斜着的一行(左下方到右上方),所以我們每次可以將問題分解爲,每次遍歷一個斜行,至於方向是從左下到↗️右上,還是右上到↙️左下,我們可以使用一個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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章