我在寻找子集生成的答案时遇到this code snippet。
start
N; //an integer
X = N
while true
print X
if( X == 0 )
break;
X = (X-1) & N;
end while
end
有人可以解释为什么这段代码有效吗?提前谢谢。
感谢您的回答。我的证据理念如下:
如果我们将N
视为掩码,重要的位是N
中1的位置。我们称之为蒙面空间。
由于X
始终是N
的子集,因此X
的倒计时就像在屏蔽空间中倒计时(在屏蔽空间中翻转的位)。
因此,X
和(X-1) & N
之间没有其他子集。
答案 0 :(得分:2)
您可以使用以下参数证明它的工作原理:
(X-1)
总是产生一个较小的数字(忽略环绕)。(X-1)&N <= (X-1)
。k & N
必须是&#34;子集&#34; N
。k
和k&N
之间的值不能是&#34;子集&#34; N
,因此你没有错过任何东西。答案 1 :(得分:2)
要了解发生了什么,你应该完全理解减法,这实际上是这里最复杂的操作。
另一种考虑减1的方法是,你开始查看最低有效位的数字,然后扫描最高位,直到找到第一位1.将每一位翻转到包括那1位
结合&
,它会抛出最低的设置位,然后将任何曾经位于该位右侧的位放回。
例如,
10110 start here
10101 subtract 1
10100 and with N
10011 subtract 1
10010 and with N
10001 subtract 1
10000 and with N
01111 subtract 1
00110 and with N