【问题标题】:How can we generate all submatrix of a given 2D matrix in java or C++?我们如何在 java 或 C++ 中生成给定二维矩阵的所有子矩阵?
【发布时间】:2017-11-18 19:11:57
【问题描述】:

我正在使用这种循环结构,但它无法生成任何给定具有 n 行和 m 列的二维矩阵的所有子矩阵。

  for(i=0;i<n;i++)
    {
        for(j=0;j<m;j++)
        {
            System.out.println("sub-MATRIX:");
            for(k=i;k<n;k++)
            {
                for(p=j;p<m;p++)
                {
                   System.out.print(arr[k][p]+" ");
                }
                System.out.println();
            }
        }
    }

例如:给定矩阵 3X3:[[1 2 3],[4 5 6],[7 8 9]] 那么它的子矩阵将是: 对于尺寸 1: [1],[2],[3],[4],[5],[6],[7],[8],[9] 尺寸 4: [[1,2],[4,5]],[[2,3],[5,6]],[[4,5],[7,8]] 和 [[5,6],[ 8,9]] 等等

【问题讨论】:

  • 请提供更多细节:输入、预期输出、实际输出是多少?
  • 子矩阵的大小?
  • 这与 C++ 有什么关系?这听起来更像是一个算法问题
  • @K.Kirsz 我添加了一个示例。任务是在给定矩阵中生成所有可能的所有大小的子矩阵
  • 这样想:你在 MxN 矩阵中寻找 UxV 矩阵的所有可能的左上角。有 (M-U+1) x (N-V+1) 个候选者。简单地遍历这些。

标签: java c++ algorithm


【解决方案1】:

您还缺少几个循环来涵盖所有情况。 PrintMatyrix() 应该有 2 个用于打印内容的嵌套循环。

  for (i = 1; i < n; ++i)
  {
    for (j = 1; j < m; ++j)
    {
      // we are at each sub matrix of size(i,j)
      for (k = 0; k <= (n - i); ++k)
      {
        for (p = 0; p <= (m - j); ++p)
        {
           // we are at submatrix of size(i,j) starting at (k,p)
           // assuming PrintMatrix(Matrix&, int rows, int cols, int r0, int c0);   
           PrintMatrix(arr, i, j, k, p);
        }
      }
    }
  }

【讨论】:

    【解决方案2】:

    如果我们有一个维度为 M x N 的矩阵,而我们正在寻找的子矩阵是维度为 K x L。如果有更优化的解决方案,请分享。

    for (int i = 0; i < m-k+1; i++) {   
                    for (int j = 0; j < n-l+1; j++) {
                        for (int p = 0; p < k; p++) {
                            for(int q = 0; q < l; q++) {
                                System.out.print(arr[i+p][j+q] + " ");
                            }
                            System.out.println();
                        }
                        System.out.println("*****************");
    
                    }
                }
    

    【讨论】:

      【解决方案3】:

      你不应该循环,你应该使用一些递归。

      这样想,对于每一行或每一列,你要么拿走它,要么扔掉它。因此,您可以先选择行,然后选择列,并根据您选择的行和列构建子矩阵。

      一些代码,

      bool rowTaken[N], columnTaken[M];
      void constructSubMatrixRow(int i)
      {
          if (i >= N) constructSubMatrixCol(0);
          rowTaken[i] = true;
          constructSubMatrix(i+1);
          rowTaken[i] = false;
          constructSubMatrix(i+1);
      }
      
      void constructSubMatrixCol(int i)
      {
          if (i >= M) printSubMatrix();
          columnTaken[i] = true;
          constructSubMatrixCol(i+1);
          columnTaken[i] = false;
          constructSubMatrixCol(i+1);
      }
      
      void printSubMatrix()
      {
          for (unsigned i = 0; i < N; i++)
              if (rowTaken[i]){
                  for (unsigned j = 0; j < M; j++)
                     if (columnTaken[j])
                        print matrix[i][j]
              }
      }
      

      【讨论】:

      • 函数 printSubMatrix() 的行和列边界是什么?
      • @mohdanishh,printSubMatrix 只是打印出使用 rowTaken 和 columnTaken 构造的子矩阵。查看更新的伪代码
      • 如果您能构造函数 printSubMatrix() 将非常有帮助,它将帮助我完全理解您的算法。谢谢
      • @mohdanishh,请刷新查看更新后的代码
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-16
      • 1970-01-01
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多