子集生成

输入n,由n得到集合D{1~n},输出集合D的所有子集;

方法1:增量构造法(依次往集合中增加一个元素)

代码:

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 #define MAXN 100+10
 4 using namespace std;
 5 
 6 int a[MAXN];
 7 
 8 void print_subset(int n, int* a, int cur)
 9 {
10     for(int i=0; i<cur; i++)   // 输出当前集合
11     cout << a[i] << " ";
12     cout << endl;
13     int s = cur ? a[cur-1] + 1 : 1;  // 集合按字典序输出,确定当前元素的最小可能值(避免输出{2,1},{1,2})这样的情况
14     for(int i=s; i<=n; i++)
15     {
16         a[cur]=i;
17         print_subset(n, a, cur+1);   // 按层次递归构造子集
18     }
19 }
20 
21 int main(void)
22 {
23     int n;
24     cin >> n;
25     print_subset(n, a, 0);
26     return 0;
27 }

 



方法2:位向量法(dfs)

代码:

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 #define MAXN 100+10
 4 using namespace std;
 5 
 6 int a[MAXN]={0};
 7 
 8 void print_subset(int n, int* a, int cur)
 9 {
10     if(cur==n+1)            // 当n(n+1-1)个元素全部递归完后打印当前集合
11     {
12         for(int i=1; i<=cur; i++)
13         if(a[i]) cout << i << " ";
14         cout << endl;
15         return;
16     }
17     a[cur]=1;              // 选第cur个元素
18     print_subset(n, a, cur+1);
19     a[cur]=0;             // 不选第cur个元素
20     print_subset(n, a, cur+1);
21 }
22 
23 int main(void)
24 {
25     int n;
26     cin >> n;
27     print_subset(n, a, 1);
28     return 0;
29 }

 



方法3:(二进制法)// 集合0~n-1的子集

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 void print_subset(int n, int s)
 5 {
 6     for(int i=0; i<n; i++)
 7     if(s&(1<<i)) cout << i << " ";
 8     cout << endl;
 9 }
10 
11 int main(void)
12 {
13     int n;
14     cin >> n;
15     for(int i=0; i<(1<<n); i++)
16     print_subset(n, i);
17     return 0;
18 }

 



posted @ 2016-09-04 11:03  geloutingyu  阅读(318)  评论(0编辑  收藏  举报