题目描述:
给定一个集合,枚举它所有可能的子集。
这道题的主流算法有三种,本文介绍最难的——二进制法(讲解在代码中)
#include<iostream>
#include<string>
#include<list>
#include<algorithm>
using namespace std;
list<list<int> > getSubstr(string A, int n){
list<list<int> > res;//用来存储结果
//从全1,也就是全选开始,每次减1,正好取完所有的子集
for(int i = (1<<n)-1; i > 0; i--){ //(1<<n)-1为2的n次方减一,正好对应n位全1的二进制数
list<int> s;
for(int j = n-1; j >= 0; j--){ //表示i右移j位,查看没位的二进制数,从而判断数组的该位是否取
if((i>>j)&1 == 1) s.push_back(A[j] - '0');//每一个小的集合对应一位数,每j个小几个push到大集合中形成一组解
}
res.push_back(s);
}
return res;
}
int main(){
string s;
cin >> s;
list<list<int> > res = getSubstr(s,s.length());
//遍历输出
for(list<list<int> >::iterator it = res.begin(); it != res.end(); it++){
//由于C++不像Java,每一个迭代器拿出来的都没法直接当作一个对象,所以这里需要定义一个临时集合
list<int> rs = *it;
for(list<int>::iterator it1 = rs.begin(); it1 != rs.end(); it1++){
cout << *it1;
}
cout << " ";
}
cout<<endl;
return 0;
}