绘制标尺的非递归程序

时间:2012-09-10 10:36:57

标签: algorithm

我正在阅读Robert Sedwick的算法。

Here is the book

页码:214。

下面的文字是参考数字的二进制表示。

罗伯特·塞德威克(Robert Sedwick)在这里提到以下程序的灵感来自对二进制数的对应关系用于绘制标尺的非递归程序,如下所述

void rule(int l, int r, int h)
  { 
    for (int t = 1, j = 1; t <= h; j += j, t++)
      for (int i = 0; l+j+i <= r; i += j+j)
        mark(l+j+i, t);
  }

在图5.10中,作者提到要非抽象地绘制尺子,我们交替绘制长度为1的图纸并跳过 位置,然后交替绘制长度为2的图画并跳过剩余的位置,等等。

我在上面有以下问题。

  1. 我的问题是作者如何提到程序的灵感来自二进制数?
  2. 在图5.10中,作者通过跳过位置意味着什么?这里有什么职位?
  3. 在图5.10中,图中的标记是什么?
  4. 请用规则(0,8,3)解释。

2 个答案:

答案 0 :(得分:1)

对于#1,如果你用二进制写下一系列数字,并屏蔽除低x位以外的所有数字,你会得到一个重复模式(例如x = 4):

 0 = 0000
 1 = 0001
 2 = 0010
 3 = 0011
 4 = 0100
 5 = 0101
...
14 = 1110
15 = 1111
16 = 0000
17 = 0001
...

如果您查找以1的字符串结尾的数字,您会看到一个有趣的模式。 将上述逆时针旋转90度以节省空间:

010101010101010101010101010101010101010101010101
001100110011001100110011001100110011001100110011 ....
000011110000111100001111000011110000111100001111
000000001111111100000000111111110000000011111111

用!:

替换(仅)1的结尾字符串
0!0!0!0!0!0!0!0!0!0!0!0!0!0!0!0!0!0!0!0!0!0!0!0!
001!001!001!001!001!001!001!001!001!001!001!001! ....
0000111!0000111!0000111!0000111!0000111!0000111!
000000001111111!000000001111111!000000001111111!

用空格替换其他所有东西,你会得到一个重复的标尺图案。

 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
   !   !   !   !   !   !   !   !   !   !   !   ! ....
       !       !       !       !       !       !
               !               !               !

如果你仔细想想,你可以看到1的弦的长度(对应于标记的长度)如何与其出现的频率以及它如何导致上面的图案相对应。

答案 1 :(得分:0)

我觉得在这里缺少一些东西的人是本文的作者,而不是读者。从本书中发布的代码缺少注释 - 特别是@param标签,以准确指出这三个参数的含义。发布的解释似乎也有些缺失。

这是我对#2的猜测: 当你看一个标尺时,0.5英寸的标记大于0.25或0.75英寸。因此,首先我们可以放置半英寸标记,然后当我们放置1/4“标记时,我们”跳过位置“,因为不需要绘制1/4”标记的一半。例如,当我们填写1“和3”之间的标记时,按1/4“计算我们有:

1.25 [跳过] 1.75 [跳过] 2.25 [跳过] ,, ...

换句话说,当放置1/4“标记时,我们实际上计算的是0.5”而不是四分之一。在本书发布的代码中,这可能是您在内部循环中看到j+j的原因。这表明j是当前标记值(前1/4,然后是1/2,然后是1/8)。由于一切都是用整数完成的,因此j = 1对应于1/16“,然后2j,4j,8j是标记值。