有这样的一个问题:
这时候二进制就派上了用场~
我们用 0,1 来表示当前位是否被保留,值为 1 则保留,为 0 则舍弃 ,如下图所示:

那么对于一个有 n 个数的集合来讲,每一位有取和不取两种状态,一共就有 2n 种状态,我们可以从 0 一直枚举到 2n 来表示所有子集的状态。
但是现在问题又来了,对与我们枚举的数,你怎么知道哪一位是 0,哪一位是 1?
这个时候就要用到位运算的知识了,对于一个数 S(子集的状态) 我们拿它和 0n 每一位 i 进行 S&(1<<i) 这样的运算就能得到对于的位是否为 1(& 运算符的特点是只有当对应位都为 1 时,运算结果才为 1)
举个栗子,S = 13,对于的二进制码为 1101
1101 & 0001 得到第一位为 1
1101 & 0010 得到第二位为 0
1101 & 0010 得到第三位为 1
1101 & 1000 得到第四位为 1
这样就得到我们取集合中的 1,3,4 位
实现代码:
for(int i = 0; i < (1<<n); i++) //二进制枚举每一个状态
for(int j = 0; j < n; j++) //枚举该状态下二进制的每一位数值
if(i&(1<<j)) //当前位是否为1
printf("%d ", a[j]);