【问题标题】:How can I iterate through a two-dimensional array in a snail mode, with a single cycle?如何以蜗牛模式迭代二维数组,单循环?
【发布时间】:2017-03-27 03:17:17
【问题描述】:

给定一个二维数组,我想以蜗牛模式遍历它并使用一个循环打印出元素.

例如,如果给定的数组是:

10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
25 26 27 28 29
30 31 32 33 34

程序应该打印出来:

10 15 20 25 30 31 32 33 34 29 24 19 14 13 12 11 16 21 26 27 28 23 18 17 22

所以从左上角开始,一直到数组的中心。

【问题讨论】:

标签: arrays algorithm matrix multidimensional-array cycle


【解决方案1】:

下面是一个 for 循环的解决方案:

仅当矩阵为:n >= m

时才有效
#include <iostream>

using namespace std;

int main()
{
//    int arr[4][3] = {{0, 9, 8} , {1, 10 , 7} , {2, 11, 6} , {3, 4, 5}};
//    int n = 4, m = 3;

    int arr[4][4] = {{0, 11, 10, 9} , {1, 12, 15, 8} , {2, 13, 14, 7} , {3, 4, 5, 6}};
    int n = 4, m = 4;

    int row = 0, col = 0, turn = 0;
    bool isTop = true;

    for(int nrElem = 0; nrElem <= (n*m); nrElem++)
    {
        //This part make the left, bottom, right part ( U form )
        if((row < n-1-turn) && (col != m-1) && (isTop == true))
        {
            cout << " " << arr[row][col];
            row++;
        } else {
            if((row == n-1-turn) && (col < m-1-turn))
            {
                cout << " " << arr[row][col];
                col++;
            } else {
                if((col == m-1-turn) && (row > 0))
                {
                    cout << " " << arr[row][col];
                    row--;
                } else {
                    isTop = false;
                }
            }
        }
        //

        //And this do the top backward parsing
        if((col > 0) && (isTop == false))
        {
            cout << " " << arr[row][col];
            col--;
        } else {
            if (isTop == false)
            {
                isTop = true;
                turn++;
                row += turn;
                col += turn;
            }
        }
    }

    cout << endl;
    return 0;
}

【讨论】:

    【解决方案2】:

    我们可以用一个循环来完成,而无需存储额外的矩阵。以下代码假定您可以使用来自C++11std::vector,并且基于来自geeks for geeks 的示例。当然,该算法在没有std::vector 的情况下也可以工作。此外,这只蜗牛是顺时针方向的,作为练习,你应该把它改成逆时针方向:)。 [我没有编译代码]

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    void printSnail(vector<vector<int>> const &matrix)
    {
      size_t nRow = matrix.size();       // Number of rows that are not printed yet
      size_t nCol = matrix[0].size();    // Number of columns that are not printed yet
    
      size_t k = 0;
      size_t l = 0;
    
      // Print all elements in the matrix
      while (k < nRow and l < nCol)
      {
        // Print first row of remaining rows
        for (size_t idx = l; idx < nCol; ++idx)
          cout << matrix[k][idx] << ' ';
        ++k;
    
        // Print last column of remaining columns
        for (size_t idx = k; idx < nRow; ++idx)
          cout << matrix[idx][nCol - 1] << ' ';
        --nCol;
    
        // Print last row of remaining rows
        if (k < nRow)
        {
          for (size_t idx = nCol - 1; idx >= l; --idx)
            cout << matrix[nRow - 1][idx] << ' ';
          --nRow;
        }
    
        // Print the first column of the remaining columns
        if (l < nCol)
        {
          for (size_t idx = nRow - 1; idx >= k; --idx)
            cout << matrix[idx][l] << ' ';
          ++l;
        }
      }
    }
    

    【讨论】:

      【解决方案3】:

      这里有一个简单的解决方案:

      • 保持与您的数组大小相同(所有单元格初始化为0)的二维数组(checkIfVisited),以便跟踪已访问的单元格。如果(i,j)1 则表示原始单元格已经被访问过。

      • 我们在dir 变量的帮助下螺旋式迭代整个数组,该变量跟踪我们当前正在遍历的方向。

      • dir = 0 表示向下移动,1 表示向右移动,2 表示向上移动,3 表示向左移动。

      • ij 超出限制,或者通过从checkIfVisited 数组中查找之前已经遍历过下一个要遍历的单元格时,我们会改变方向。

      我对上述算法有一个简单的 C++ 实现:

      #include <iostream>
      using namespace std;
      int main() 
      {
          int arr[5][5] = {10, 11, 12, 13, 14,
                           15, 16, 17, 18, 19,
                           20, 21, 22, 23, 24,
                           25, 26, 27, 28, 29,
                           30, 31, 32, 33, 34};
      
          int checkIfVisited[5][5] = {0,0,0,0,0,
                                      0,0,0,0,0,
                                      0,0,0,0,0,
                                      0,0,0,0,0,
                                      0,0,0,0,0};
          int i,j,dir,countVisited;
          dir = 0;
          countVisited = 0;
          i = 0;
          j = 0;
          while(countVisited<5*5)
          {
              cout<<arr[i][j]<<" ";
              checkIfVisited[i][j]=1;
              if(dir==0)
              {
                  countVisited++;
                  if(i+1>4 || checkIfVisited[i+1][j]==1){
                      dir=1;
                      j++;
                  }
                  else
                      i++;
              }
              else if(dir==1)
              {
                  countVisited++;
                  if(j+1>4 || checkIfVisited[i][j+1]==1){
                      dir=2;
                      i--;
                  }
                  else
                      j++;
              }
              else if(dir==2)
              {
                  countVisited++;
                  if(i-1<0 || checkIfVisited[i-1][j]==1){
                      dir=3;
                      j--;
                  }
                  else
                      i--;
              }
              else
              {
                  countVisited++;
                  if(j-1<0 || checkIfVisited[i][j-1]==1){
                      dir=0;
                      i++;
                  }
                  else
                      j--;
              }
          }
      
          return 0;
      }
      

      输出: 10 15 20 25 30 31 32 33 34 29 24 19 14 13 12 11 16 21 26 27 28 23 18 17 22

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-04-23
        • 1970-01-01
        • 2019-03-16
        • 1970-01-01
        • 1970-01-01
        • 2019-06-02
        • 1970-01-01
        相关资源
        最近更新 更多