【问题标题】:c lineal draw in a consolec 在控制台中进行线性绘制
【发布时间】:2015-04-11 14:35:18
【问题描述】:

我正在尝试在 c 中的控制台中绘制一条直线。

我有一个递归程序:

void mark(int m, int h) {
  printf("set a mark at %d of length %d\n",m,h);
}

void ruler(int l, int r, int h) {
  int m = (l+r)/2;
  if (h>0) {
    mark(m, h);
    ruler(l, m, h-1);
    ruler(m, r, h-1);
  }
}

我必须画一条直线:

我的问题是我有第一行标记(4,3)(中心线),然后我必须再放一条线,但我有2条线,另外两条在中间。

有人知道怎么做吗?或者如何将其转换为非递归算法?

谢谢 最好的问候

【问题讨论】:

  • 你能举一个你期望得到的例子吗?我对“......然后我必须换行”这句话感到困惑。您的递归程序,假设 mark 函数正常工作,应该绘制中心线,将标尺分成两半并在每一半中放置一条中心线,依此类推。
  • 如果我没看错:按原样打印“在长度为 3 的 4 处;在长度为 2 的 2 处;在长度为 1 的 1 处;在长度为 1 的 3 处;在长度为 2 的 6;长度为 1 的 5;长度为 1 的 7;",但是您想先打印长度为 3 的行,然后是长度为 2 的行,然后是长度为 1 的行?
  • 你说得对,问题是,我必须打印所有长度为 2 的行,但程序在 2 行之间也给了我 1 行!
  • 建议使用ruler(l, m, h-1); mark(m, h); ruler(m, r, h-1);重新排序,以升序工作。

标签: c console console-application


【解决方案1】:

想象实数线上的线段 [0, 1],并计算 ruler(0, 1, n):

  • 第 1 步:首先将长度为 n 的标记放置在中间,在 1/2 处,将线段分成两半
  • 第 2 步:然后将长度为 n-1 的两个标记放在每一半的中间:1/4 和 3/4。
  • 第 3 步:然后将长度为 n-2 的四个标记放置在:1/8、3/8、5/8、7/8。
  • 第 4 步:然后将长度为 n-3 的八个标记放置在:1/16、3/16、5/16、... 15/16。李>

...

  • 第 n 步:最后,将长度为 1 的 2n-1 个标记放置在:1/2n、3/2n , 5/2n, ...(2n-1)/2n.

对于 标尺(l, r, n),这些分数将是相同的,但取而代之的是例如,3/4,你将把标记放在 ab 之间的四分之三处。这很简单:l + (r - l) * 3/4。

将这种方法翻译成 C 代码,我们可以将您的函数以非递归方式编写为:

void ruler(int l, int r, int n) {
    int step, num, denom;
    for (step = 1; step <= n; step++) {
        denom = 1 << step;
        for (num = 1; num < denom; num += 2)
            mark(l + (r-l) * num / denom, n - (step - 1));
    }
}

【讨论】:

  • 谢谢这是在非递归算法中转换递归的好方法,这问了我的一个问题。但我现在找不到怎么画。我试过这样: for(i = 0; i
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 2016-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多