第n个格雷码

计算第n个格雷码的公式为:
(n-1) XOR (floor((n-1)/2))  
(Source: wikipedia)
我把它编码为:
int gray(int n)
{
  n--;
  return n ^ (n >> 1);
}
有人可以解释上述公式是如何工作的,或者可能是它的推导?     
已邀请:
如果你看一下二进制计数序列,你会注意到,相邻的代码在最后几位(没有空洞)有所不同,所以如果你对它们进行xor,则会出现几个尾随1的模式。此外,当您向右移动数字时,xors也将向右移位:(A xor B)>> N == A >> N xor B >> N.
    N                    N>>1                  gray
 0000           .        0000           .      0000           .
    | >xor = 0001             >xor = 0000           >xor = 0001
 0001          .         0000          .       0001          .
   || >xor = 0011           | >xor = 0001           >xor = 0010
 0010           .        0001           .      0011           .
    | >xor = 0001             >xor = 0000           >xor = 0001
 0011         .          0001         .        0010         .
  ||| >xor = 0111          || >xor = 0011           >xor = 0100
 0100                    0010                  0110
原始Xor结果和移位结果在单个位中有所不同(我用上面的点标记它们)。这意味着如果你对它们进行xor,你将获得1位设置的模式。所以,
(A xor B) xor (A>>1 xor B>>1) == (A xor A>>1) xor (B xor B>>1) == gray (A) xor gray (B)
由于xor给出了不同位的1,它证明了,相邻代码的区别仅在于单个位,而这是我们想要得到的格雷码的主要特性。 因此,为了完整性,可以证明,N可以从其N ^(N >> 1)值恢复:知道第n位代码,我们可以使用xor恢复第n-1位。
A_[bit n-1] = A_[bit n] xor gray(A)_[bit n-1]
从最大位开始(它用0进行xored),因此我们可以恢复整数。     
通过归纳证明。 提示:
1<<k
(1<<(k+1))-1
的值是
1<<(k-1)
(1<<k)-1
值的两倍加上零或一。 编辑:这太令人困惑了。我的意思是,
gray(2*n)
gray(2*n+1)
按某种顺序分别为
2*gray(n)
2*gray(n)+1
。     
您参考的维基百科条目以非常迂回的方式解释了等式。 但是,从这开始是有帮助的:   因此编码是稳定的   感觉一旦二进制数   出现在Gn中它出现在同一个   所有较长名单中的位置;所以   谈谈这个问题是有道理的   反射格雷码的值   数量:G(m)=第m次反射   格雷码,从0开始计数。 换句话说,
Gn(m) & 2^n-1
Gn-1(m & 2^n-1)
~Gn-1(m & 2^n-1)
。例如,
G(3) & 1
G(1)
~G(1)
。现在,我们知道如果
m
大于
2^n-1
Gn(m) & 2^n-1
将是反射(按位反转)。 换一种说法:
G(m, bits), k= 2^(bits - 1)
G(m, bits)= m>=k ? (k | ~G(m & (k - 1), bits - 1)) : G(m, bits - 1)
G(m, 1) = m
完整地计算出数学,对于从零开始的格雷码,你得到
(m ^ (m >> 1))
。     
增加一个数字,当你按位时,将所有尾随的数字翻转为零,将最后的零翻转为1。这是翻了很多位,格雷码的目的是让它完全一个。这种转换使得两个数字(增量之前和之后)在所有被翻转的位上相等,除了最高的一个。 之前:
011...11
     + 1 
---------
100...00
后:
010...00
     + 1
---------
110...00
^<--------This is the only bit that differs 
          (might be flipped in both numbers by carry over from higher position)
n ^ (n >> 1)
更容易计算,但似乎只将尾随
011..1
改为
010..0
(即将整个拖尾块归零1除了最高1)和
10..0
11..0
(即在尾随0中翻转最高0)足以获得格雷码。     

要回复问题请先登录注册