二进制枚举子集--最通俗易懂的讲解

子集:是一个数学概念:如果集合A任意一个元素都是集合B的元素,那么集合A称为集合B子集

 二进制:是计算技术中广泛采用的一种数制二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”

我们就是利用了二进制的特性 ,比如说有5个木棍的长度:4, 8, 2, 6, 7。我们就可以用01代表不选

如果选出长度为4、2、6的木棍,则如下表:

                      4                    8                  2            6             7
二进制                     1                     0                  1            1             0
木棍的状态                    选                  不选                 选           选           不选

上面说有5个木棍如果全选的话就是11111对应的十进制数就是31,也就是(2^n)-1个集合,我们用(1 << n)- 1表示,区间【1,2^n-1】这个区间上每一个整数代表一个集合,上表就是数字为22(二进制:10110)所代表的集合:4、2、6。

所以我们遍历每一个集合:

for(int i = 0; i < (1 << n); i++)

设s = 13(二进制为1101)代表我们选0 2 3位置上的数值;

那么我们如何找到每个位置上的数值呢?

我们遍历的是二进制的十进制表示(比如13),我们当然可以转化为二进制在枚举每一位,但是,这很麻烦;

一个很巧妙的方式就是利用位运算。

1<<0=1(0);

1<<1=2(10);

1<<2=4(100);

1<<3=8(1000);

1<<4=16(10000);

...

1<<7=128(10000000);

...

看出来了吧!我们只需要将13&(1<<i)我们便可以得到每一位是不是1 (1<< i 除了那一位,剩余的都是0,所以我们就可以得到那一位是不是1)

补充一波位运算的知识吧:

按位与运算符(&)

参加运算的两个数据,按二进制位进行“与”运算。

运算规则:0&0=0;  0&1=0;   1&0=0;    1&1=1;

      即:两位同时为“1”,结果才为“1”,否则为0

例如:3&5  即 0000 0011& 0000 0101 = 00000001  因此,3&5的值得1。

左移运算(<<)

 a << b就表示把a转为二进制后左移b位(在后面添b个0)。例如100的二进制为1100100,而110010000转成十进制是400,那么100 << 2 = 400。可以看出,a << b的值实际上就是a乘以2的b次方,因为在二进制数后添一个0就相当于该数乘以2(这样做要求保证高位的1不被移出)。
通常认为a << 1比a * 2更快,因为前者是更底层一些的操作。因此程序中乘以2的操作请尽量用左移一位来代替。

因此,我们便有了:

for(int j = 0; j < n; j++)
        if(i & (1 << j))
            printf(" %d ",a[j]);

那么完整的代码就是: 

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < (1<<n); i++) //从0~2^n-1个状态
    {
        for(int j = 0; j < n; j++) //遍历二进制的每一位
        {
            if(i & (1 << j))//判断二进制第j位是否存在
            {
                printf("%d ",j);//如果存在输出第j个元素
            }
        }
        printf("\n");
    }
    return 0;
}

例题1:ALGO-115_蓝桥杯_算法训练_和为T点击这里

例题2:HDU5616--Jam's balance点击这里

参考:

https://www.cnblogs.com/SunQi-lvbu/p/7305779.html

https://blog.csdn.net/riba2534/article/details/79834558

猜你喜欢

转载自blog.csdn.net/sugarbliss/article/details/81099340