思路一:使用dfs递归将所有的情况都列举出来,增加一个”选与不选”的判断
思路二:使用二进制,集合个数为n时,一共有 2^n 个子集,正好对应一个8位的二进制数,每一位1代表选,0代表不选
[注]思路一中的判断选与不选可以开一个bool数组也可以用二进制位来操作
方法一:用dfs来递归,用bool数组来判断是否选择当前数字
#include <cstring>
#include <iostream>
using namespace std;
const int N = 20;
int n;
bool st[N];
void dfs(int u)
{
if(u > n)
{
for(int i = 1; i <= n; i ++)
if(st[i])
cout << i << ' ';
cout << endl;
return;
}
// 选当前点
st[u] = true;
dfs(u + 1);
// 不选当前点
st[u] = false;
dfs(u + 1);
}
int main()
{
cin >> n;
dfs(1);
return 0;
}
方法二:利用二进制的原理(2^n个子集对应一个n位的二进制数)
1 << n 表示将1左移n位==2^n
i >> j - 1 & 1 表示将i右移j-1位然后将个位与1运算(其实就是判断第j位是不是1)
& | 位运算的与、或操作,i & 1用来判断是不是1,i | 1 用来将当前位置一
#include <cstring>
#include <iostream>
using namespace std;
const int N = 20;
int nums[N];
int main()
{
int n;
cin >> n;
// 通过二进制位的变化进行枚举
for (int i = 1; i <= 1 << n; i ++)
{
// 遍历每一位,如果该位为 1,表示选择当前位置的数
for (int j = 1; j <= n; j ++)
if (i >> j - 1 & 1)
cout << j << ' ';
cout << endl;
}
return 0;
}