Algorithm 生成给定二进制字符串的子集,这段代码是如何工作的?

Algorithm 生成给定二进制字符串的子集,这段代码是如何工作的?,algorithm,subset,Algorithm,Subset,我在寻找子集生成的答案时遇到 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的倒计时就像在屏蔽空间中倒计时一样

我在寻找子集生成的答案时遇到

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
之间没有其他子集。您可以用以下参数证明它是有效的:

  • (X-1)
    始终生成较小的数字(忽略环绕)

  • (X-1)&N您可以用以下参数证明它有效:

  • (X-1)
    始终生成较小的数字(忽略环绕)

  • (X-1)&N要理解发生了什么,你应该完全理解减法,它实际上是这里最复杂的运算

    另一种思考减法1的方法是,从最低有效位开始看数字,然后朝最高有效位扫描,直到找到第一个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
    

    要理解发生了什么,你应该完全理解减法,这实际上是这里最复杂的运算

    另一种思考减法1的方法是,从最低有效位开始看数字,然后朝最高有效位扫描,直到找到第一个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
    

    这并不完全表明
    X
    在每次迭代中变小:如果
    X
    N
    中最右边的1位右边有一个1位,那么
    X=(X-1)&N
    将保持
    X&N
    不变。所以我们需要证明这是不可能的。显然,它不能在第一次迭代时,当
    X==N
    时,
    X
    的每次更新都以一个和
    N
    结束,所以这样的位永远不会出现。@j_random_hacker,但这是这个答案第3点的结果,对吗?@harold:第3点确实意味着从第2次开始的每次迭代都会产生一个不同的值
    X&N
    ,但作为一个证据,这篇文章是不完整的。如前所述,第1点实际上是不相关的,因为它只描述了一个中间结果。相反,我们需要的是“如果
    X&~N==0
    ,那么
    (X-1)&N
    ,假设继续成立(即
    ((X-1)&N)&~N==0
    )”,然后是一个声明,表明该假设(
    X&~N==0
    )在第一次迭代中保持不变。这并不表明
    X
    在每次迭代中变小:如果
    X
    N
    中最右边的1位右边有一个1位,那么
    X=(X-1)&N
    将保持
    X&N
    不变。所以我们需要证明这是不可能的。显然,它不能在第一次迭代时,当
    X==N
    时,
    X
    的每次更新都以一个和
    N
    结束,所以这样的位永远不会出现。@j_random_hacker,但这是这个答案第3点的结果,对吗?@harold:第3点确实意味着从第2次开始的每次迭代都会产生一个不同的值
    X&N
    ,但作为一个证据,这篇文章是不完整的。如前所述,第1点实际上是不相关的,因为它只描述了一个中间结果。相反,我们需要的是“如果
    X&~N==0
    ,那么
    (X-1)&N
    ,假设继续成立(即
    ((X-1)&N)&~N==0
    )”,然后是一条语句,表明该假设(
    X&~N==0
    )在第一次迭代中成立。