举例:比如求3的子集,也就是0,1,2这三个数能构成的所有集合
高中知识:3个数,子集个数为个,联想三位二进制数能表示的数字个数也是八个,对应如下:
子集 | 空集 | 0 | 1 | 0 1 | 2 | 0 2 | 1 2 | 0 1 2 |
二进制数 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
注意,哪一位有1,子集就包含哪一个数字,比如 110 ,第一位和第二位有1,那么就表示子集 1 2 ;再比如 101 ,第0位和第2位有1,那么就表示子集 0 2
这样我们求3的子集只要表示出三位二进制能表示的所有数,然后找1的位置就行了
上代码:
#include<bits/stdc++.h>
using namespace std;
void print_subset(int n)
{
for(int i=0;i<(1<<n);i++) //列出所有二进制组合,1<<n为移位运算,1后添n个0,巧妙表示2的n次幂
{
for(int j=0;j<n;j++) //用j来寻找i对应的二进制中1在第几位
{
if(i & (1<<j)) //这个循环中,j分别表示001,010,100,用与运算探测i中第几位有1
cout<<j<<" "; //输出j
}
cout<<endl;
}
}
int main()
{
int n;
cin>>n;
print_subset(n);
}
这个代码中,i分别遍历000~111,比如在i遍历110时
j的循环中j分别表示001,if里面不成立
j再表示010,就是1,与i相与,成立,输出1
j再表示100,就是2,与i相与,成立,输出2
就是1 和 2 这个小子集