提问者:小点点

“b=(b-x)&x”是什么意思?


假设x是一个集合,下面的代码遍历集合x的子集:

int b = 0;
do {
// process subset b
} while (b=(b-x)&x);

我看到了这篇关于位操作的文章,以及它是如何用来表示集合的。

表达式b=(b-x)&x是什么意思? 它是怎么工作的? 在do while循环中,我熟悉==,但不熟悉=。 那是怎么运作的? 当(b-x)&x的值变为零时,循环是否终止?

代码的用法如下:

#include <iostream>

using namespace std;

void subsets(int x, int b){
    do{
        cout << b<<"\n";
    }while(b = (b-x)&x);
}

int main()
{
    int x = (1<<1)|(1<<3)|(1<<4)|(1<<8);
    int b = 0;
    subsets(x, b);
    return 0;
}

上面代码给出的输出是:

0
2
8
10
16
18
24
26
256
258
264
266
272
274
280
282

这段代码摘自《竞争性编程指南:通过竞赛学习和改进算法》一书


共2个答案

匿名用户

容易零件优先:

当(b-x)&x的值变为零时,循环是否终止? 在do while循环中,我熟悉==,但不熟悉=。 那是怎么运作的?

是的。

do/while循环如下:

do{
    cout << b<<"\n";
}while(b = (b-x)&x);

执行以下步骤:

  1. 执行cout<<<; b<<“\n”;.
  2. 执行b=(b-x)&x并记住结果。
  3. 如果结果不为零,请返回步骤1.

=是分配。 它将变量设置为值,如i=0;。 但是。。。 嗯? 作业结果如何? 在C语言中,赋值的结果就是被赋值的值。 这允许您编写a=b=c=0;,将三个变量abc设置为0。 这相当于a=(b=(c=0));,即它将c设置为0,然后将b设置为该结果,然后将a设置为该结果。 (在C++中,可以编写一个不遵循此规则的类,但我们这里只处理ints,而不是类)

有些人喜欢用这个伎俩让他们的代码变得更短。 你可以这样写:

do{
    cout << b<<"\n";
    b = (b-x)&x;
}while(b);

表达式b=(b-x)&x是什么意思?

=是分配。 -是减法。 &是“按位与”。

这将从b中减去x。 然后,它用x对答案进行逐位加和。 然后,它将b设置为该问题的答案。

什么是按位与? 按位AND是这样一种操作,在这种操作中,你记下二进制数字,对齐它们,然后创建一个新的数字,如果两个输入中的位都是1,则每个位都是1,否则为0。 示例:

    01011010 = 90
  & 11101000 = 232
  -----------------
    01001000 = 72

so 90(&P; 232等于72。

它是怎么工作的?

这个程序基本上是把数字当作二进制来处理的。 x中的每个位为1表示某物“在集合中”,或为0表示该物不在集合中。

b然后遍历这些位的所有可能组合。 B=(b-x)&; X;有点“巫毒魔咒”的意思,按顺序将组合改为下一个,例如:

  - 000000000 <- b the first time
    011001001 <- x
 -----------------
    100110111 <- b-x
  & 011001001 <- x
 -----------------
    000000001 <- (b-x)&x (b the second time)
  - 011001001 <- x
 -----------------
    100111000 <- b-x
  & 011001001 <- x
 -----------------
    000001000 <- (b-x)&x (b the third time)
  - 011001001 <- x
 -----------------
    100111111 <- b-x
  & 011001001 <- x
 -----------------
    000001001 <- (b-x)&x (b the fourth time)
 ...etc...

你可以肯定,发明这个把戏的人是非常聪明的。

匿名用户

“所有内置赋值运算符返回*this”[cppreference]

这意味着b=a是返回对b的引用的表达式(对于原始类型,例如int B;int a;)。

在您的示例中,B=(b-x)&x在将(b-x)&x分配给B之后返回对B的引用。

在条件检查中(例如,在while循环中),此值隐式转换为bool,其中0=>; false和其他任何东西=>; true。 循环

do {
// process subset b
} while (b=(b-x)&x);

只要(b-x)&x!=0就会重复

相关问题