子集生成
#include <iostream>
#include <cstring>
using namespace std;
int a[20]; //存放子集的集合
//n表示元素个数和最小的不可取数,cur表示当前下标,初始值为0
void print_subset1(int n,int *a,int cur) //增量构造法,每次从可取数中取一个尽可能小的数放入子集再打印。
{
for(int i=0;i<cur;i++) cout<<a[i]<<","; //输出当前集合
cout<<endl;
int s=cur;
if(s>0) s=a[cur-1]+1; //若cur在1及其以后的位置,则s取前一个数加1的数,为的是尽可能去最小数
else s=0; //后一个数必须比前一个数大,才可以保证各个子集的集合互异性
for(int j=s;j<n;j++) //a[cur]的所有可取值j
{
a[cur]=j; //赋值
print_subset1(n,a,cur+1); //进行下一轮递归,扩充子集
}
}
void print_subset2(int n,int *a,int cur) //位向量法,枚举所有可能
{ //a数组存放的是下标i是否存在于子集中
if(cur==n) //当n个元素的存在与否已确定,打印子集
{
for(int i=0;i<=n;i++)
if(a[i]==1) cout<<i<<",";
cout<<endl;
}
else{ //枚举所有情况
a[cur]=1; print_subset2(n,a,cur+1);
a[cur]=0; print_subset2(n,a,cur+1);
}
}
int main()
{ int n;
while(cin>>n&&n)
{
memset(a,0,sizeof(a));
print_subset2(n,a,0);
}
return 0;
}