【问题标题】:Recursively print a matrix递归打印矩阵
【发布时间】:2018-03-29 11:46:53
【问题描述】:

所以,我试图从我的算法课程书中解决这个练习。该练习要求通过将矩阵细分为更小的正方形(矩阵始终是 2 的幂)来重复打印矩阵并打印其中的内容。 正方形必须从左上角然后顺时针方向打印。

所以一个例子是:

0 0 0 0
0 0 0 0
0 1 1 1
0 0 0 0

程序应该打印:

  1. 0 0 0 0
    0 0 0 0
    0 1 1 1
    0 0 0 0

  2. 0 0
    0 0

  3. 0 0
    0 0

  4. 0 1
    0 0

  5. 1 1
    0 0

等等。

到目前为止我尝试的是这样的(使用 C 来检查它是否正确):

void subdivide(int x1,int x2,int y1,int y2,int n){
    if(n==0){return;}
    else{
        n = n/2;
        subdivide(x1,x2/2,y1,y2/2,n);
        subdivide(x1,x2/2,y2/2,y2,n);
        subdivide(x2/2,x2,y2/2,y2,n);
        subdivide(x2/2,x2,y1,y2/2,n);
    }
    return;
}

但它并不完全适用于 8x8 矩阵,因为它无法到达从 (4,4) 到 (6,6) 或 (6,6) 和 (8,8) 的角落。

【问题讨论】:

  • 你尝试调试了吗?

标签: c algorithm recursion matrix


【解决方案1】:
#include <stdio.h>

void dump(int depth, int y1, int x1, int y2, int x2) {
   char indent[depth+1];

   for (int i=0; i<depth; ++i)
      indent[i] = ' ';

   indent[depth] = 0;

   printf("%s(%d,%d)(%d,%d)\n", indent, y1, x1, y2, x2);
}

// Assumes y1<=y2 && x1<=x2
void subdivide(int depth, int y1, int x1, int y2, int x2) {
   dump(depth, y1, x1, y2, x2);
   ++depth;

   int ym = (y2+y1+1)/2;
   int xm = (x2+x1+1)/2;
   if (y1!=y2 && x1!=x2) {
      if (y1==y2) {
         subdivide(depth, y1, x1, y1, xm-1);
         subdivide(depth, y1, xm, y1, x2);
      }
      else if (x1==x2) {
         subdivide(depth, y1, x1, ym-1, x1);
         subdivide(depth, ym, x1, y2,   x1);
      }
      else {
         subdivide(depth, y1, x1, ym-1, xm-1);
         subdivide(depth, y1, xm, ym-1, x2);
         subdivide(depth, ym, x1, y2,   xm-1);
         subdivide(depth, ym, xm, y2,   x2);
      }
   }
}

int main(void) {
   subdivide(0, 1,1, 8,8);
   printf("\n");
   subdivide(0, 1,1, 7,7);
   return 0;
}

输出:

$ gcc -Wall -Wextra -pedantic --std=c99 -o a a.c && a
(0,0)(7,7)
 (0,0)(3,3)
  (0,0)(1,1)
   (0,0)(0,0)
   (0,1)(0,1)
   (1,0)(1,0)
   (1,1)(1,1)
  (0,2)(1,3)
   (0,2)(0,2)
   (0,3)(0,3)
   (1,2)(1,2)
   (1,3)(1,3)
  (2,0)(3,1)
   (2,0)(2,0)
   (2,1)(2,1)
   (3,0)(3,0)
   (3,1)(3,1)
  (2,2)(3,3)
   (2,2)(2,2)
   (2,3)(2,3)
   (3,2)(3,2)
   (3,3)(3,3)
 (0,4)(3,7)
  (0,4)(1,5)
   (0,4)(0,4)
   (0,5)(0,5)
   (1,4)(1,4)
   (1,5)(1,5)
  (0,6)(1,7)
   (0,6)(0,6)
   (0,7)(0,7)
   (1,6)(1,6)
   (1,7)(1,7)
  (2,4)(3,5)
   (2,4)(2,4)
   (2,5)(2,5)
   (3,4)(3,4)
   (3,5)(3,5)
  (2,6)(3,7)
   (2,6)(2,6)
   (2,7)(2,7)
   (3,6)(3,6)
   (3,7)(3,7)
 (4,0)(7,3)
  (4,0)(5,1)
   (4,0)(4,0)
   (4,1)(4,1)
   (5,0)(5,0)
   (5,1)(5,1)
  (4,2)(5,3)
   (4,2)(4,2)
   (4,3)(4,3)
   (5,2)(5,2)
   (5,3)(5,3)
  (6,0)(7,1)
   (6,0)(6,0)
   (6,1)(6,1)
   (7,0)(7,0)
   (7,1)(7,1)
  (6,2)(7,3)
   (6,2)(6,2)
   (6,3)(6,3)
   (7,2)(7,2)
   (7,3)(7,3)
 (4,4)(7,7)
  (4,4)(5,5)
   (4,4)(4,4)
   (4,5)(4,5)
   (5,4)(5,4)
   (5,5)(5,5)
  (4,6)(5,7)
   (4,6)(4,6)
   (4,7)(4,7)
   (5,6)(5,6)
   (5,7)(5,7)
  (6,4)(7,5)
   (6,4)(6,4)
   (6,5)(6,5)
   (7,4)(7,4)
   (7,5)(7,5)
  (6,6)(7,7)
   (6,6)(6,6)
   (6,7)(6,7)
   (7,6)(7,6)
   (7,7)(7,7)

(0,0)(6,6)
 (0,0)(2,2)
  (0,0)(0,0)
  (0,1)(0,2)
   (0,1)(0,1)
   (0,2)(0,2)
  (1,0)(2,0)
   (1,0)(1,0)
   (2,0)(2,0)
  (1,1)(2,2)
   (1,1)(1,1)
   (1,2)(1,2)
   (2,1)(2,1)
   (2,2)(2,2)
 (0,3)(2,6)
  (0,3)(0,4)
   (0,3)(0,3)
   (0,4)(0,4)
  (0,5)(0,6)
   (0,5)(0,5)
   (0,6)(0,6)
  (1,3)(2,4)
   (1,3)(1,3)
   (1,4)(1,4)
   (2,3)(2,3)
   (2,4)(2,4)
  (1,5)(2,6)
   (1,5)(1,5)
   (1,6)(1,6)
   (2,5)(2,5)
   (2,6)(2,6)
 (3,0)(6,2)
  (3,0)(4,0)
   (3,0)(3,0)
   (4,0)(4,0)
  (3,1)(4,2)
   (3,1)(3,1)
   (3,2)(3,2)
   (4,1)(4,1)
   (4,2)(4,2)
  (5,0)(6,0)
   (5,0)(5,0)
   (6,0)(6,0)
  (5,1)(6,2)
   (5,1)(5,1)
   (5,2)(5,2)
   (6,1)(6,1)
   (6,2)(6,2)
 (3,3)(6,6)
  (3,3)(4,4)
   (3,3)(3,3)
   (3,4)(3,4)
   (4,3)(4,3)
   (4,4)(4,4)
  (3,5)(4,6)
   (3,5)(3,5)
   (3,6)(3,6)
   (4,5)(4,5)
   (4,6)(4,6)
  (5,3)(6,4)
   (5,3)(5,3)
   (5,4)(5,4)
   (6,3)(6,3)
   (6,4)(6,4)
  (5,5)(6,6)
   (5,5)(5,5)
   (5,6)(5,6)
   (6,5)(6,5)
   (6,6)(6,6)

【讨论】:

    【解决方案2】:

    您需要在缩放之前调整位置。我不确定您为边界使用的约定(包括或不包括),但如果您想显示 x 范围 [4, 8),即 x 索引 4(包括)到 x 索引 8(不包括),那么这需要分解为 [4, 6) 和 [6, 8) (第一个数字包含,第二个不包含)。

    但是您使用的是 [x1, x2/2),即 [4, 4),以及 [x2/2, x2),即 [4, 8),这是您的原始范围。

    假设一个独占上界,你需要使用:

    [x1, (x1+x2)/2)
    [(x1+x2)/2, x2)
    

    这会根据需要产生 [4, 6) 和 [6, 8]。

    【讨论】:

    • 是的,我也想通了。但它仍然没有真正按照预期完成完整的顺时针圆圈。问题在于以递归方式执行此操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    相关资源
    最近更新 更多