题目描述:
给定一个集合,枚举它所有可能的子集。
这道题的主流算法有三种,本文介绍最难的——二进制法(讲解在代码中)
#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; }