1 //子集生成算法:给定一个集合,枚举所有可能的子集。 2 //为了简单起见,讨论的方法中没有重复元素 3 4 //增量构造法 5 #include<cstdio> 6 #include<cmath> 7 void print_subset(int n,int* A,int cur) 8 { 9 for(int i = 0 ; i < cur; ++i) printf("%d",A[i]); 10 printf(" "); 11 int s = cur ? A[cur-1]+1 : 0; //确定当前元素的最小可能值、 12 for(int i = s; i < n; ++i){ 13 A[cur]=i; 14 print_subset(n,A,cur+1); //递归构造子集、 15 } 16 } 17 int main() 18 { 19 int A[10],n; //这种方法只适合求从0~n-1的连续整数的子集 20 scanf("%d",&n); 21 for(int i=0;i<n;++i) 22 scanf("%d",&A[i]); 23 print_subset(n,A,0); 24 }
1 //位向量法 2 //构造一个位向量B[i],而不是直接构造子集本身,其中B[i]=1,当且仅当i在自己A中. 3 void print_subset(int n,int* B,int cur) 4 { 5 if(cur==n){ 6 for(int i=0;i<cur;++i) 7 if(B[i]) printf("%d",i); 8 printf(" "); 9 return; 10 } 11 B[cur]=1; //选第cur个元素 12 print_subset(n,B,cur+1); 13 B[cur]=0; //不选第cur个元素 14 print_subset(n,B,cur+1); 15 }
1 //二进制表示子集法、 2 //下面程序输出子集S对应的各个元素 3 void print_subset(int n,int s) 4 { 5 for(int i=0;i<n;++i) 6 if(s&(1<<i)) printf("%d",i); 7 printf(" "); 8 //枚举子集和枚举整数一样 9 for(int i=0;i<(1<<n);++i) //枚举各子集对应的编码 10 print_subset(n,i); 11 } 12 //从代码量看,枚举子集的最简单方法是二进制法、 13 //当用二进制表示子集时,位运算中的按位与、或、异或对应集合的交、并和对称差
要看回溯法了、先巩固一下递归