增量构造法
还是递归的方法,通过每次添加一个元素到集合里来直接构造子集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include <iostream>
using namespace std;
void print_subset(int n,int* A,int cur);
int A[8];
int main() { print_subset(5,A,0); return 0; }
void print_subset(int n,int* A,int cur) { int i; for(i=0;i<cur;i++) printf("%d",A[i]); printf("\n"); int s = cur?A[cur-1]+1 : 0; for(i=s;i<n;i++){ A[cur]=i; print_subset(n,A,cur+1); } }
|
位向量法
不再是直接构造集合,而是通过数组B来标记某个数是否存在于子集之中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include <iostream>
using namespace std;
void print_subset(int n,int* B,int cur);
int B[8];
int main() { print_subset(5,B,0); return 0; }
void print_subset(int n,int* B,int cur) { if(cur==n){ for(int i=0;i<cur;i++) if(B[i]) printf("%d",i); printf("\n"); return; } B[cur]=1; print_subset(n,B,cur+1); B[cur]=0; print_subset(n,B,cur+1); }
|
二进制法
二进制法也和位向量法一样是去标记一个元素是否存在于子集之中而不是直接去构造子集,但它使用的是二进制位来标记
比如0100011000110111(最右边是0)表示的是0存在,1存在,2存在,3不存在,4存在…14存在,15不存在这样,所以此时集合就是{0,1,2,4,5,9,10,14}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| void print_subset(int n,int s);
int A[8];
int main() { int n=5; for(int i=0;i<(1<<n);i++) { print_subset(n, i); } return 0; }
void print_subset(int n,int s) { for(int i=0;i<n;i++) if(s&(1<<i)) printf("%d ",i); printf("\n"); }
|