求一個集合所有可能的子集
阿新 • • 發佈:2019-02-07
【1】增量構造法
一次選出一個元素放到集合中
<pre name="code" class="cpp">#include<iostream> #include<vector> using namespace std; const int MAX = 100; int layer = -1; //遞迴層數 int count1 = 0; void print_subset(int n, int *A, vector<int> &vi, int cur) { cout << "layer:" << (++layer)<<endl; count1++; for (int i = 0; i < cur; i++) { cout << vi[A[i]] << " "; } cout << endl; int s = cur ? A[cur - 1] + 1 : 0;//使用定序的技巧,規定集合A中所有元素的編號從小到大排列,就不會將{1,2}按照{1,2}與{2,1}輸出兩次了 for (int i = s; i < n; i++) { A[cur] = i; print_subset(n, A, vi, cur + 1); } layer--; } int main() { int n,m,B[MAX]; scanf("%d", &n); vector<int> vec; for (int i = 0; i < n; i++) { cin >> m; vec.push_back(m); } print_subset(n, B, vec, 0); cout << "number of set:" << count1 << endl; return 0; }
【位向量法】
構造一個位向量B[i],其中當B[i]==1的時候i元素在子集a[]中,B[i]==0時不在子集a[]中。
#include<cstdio> #include<iostream> #include<vector> using namespace std; const int MAX = 100; int count1 = 0; int layer = -1; void fullCombination(vector<int> &vi,int n, int* B, int cur) { cout<<"layer:"<<(++layer)<<endl; if (cur == n) { count1++; for (int i = 0; i < cur; i++) { if (B[i]) cout << vi[i] << " "; // 列印當前集合 } printf("\n"); layer--; return; } B[cur] = 1; // 選第cur個元素 fullCombination(vi,n, B, cur + 1); B[cur] = 0; // 不選第cur個元素 fullCombination(vi, n, B, cur + 1); layer--; } int main() { int B[MAX], n,m; vector<int>vec; cin >> n; for (int i = 0; i < n; i++) { cin >> m; vec.push_back(m); } fullCombination(vec,n, B, 0); cout << count1 << endl; return 0; }
【3】二進位制法
#include<cstdio> #include<iostream> #include<vector> using namespace std; void print_subset( int n, int s)//列印{0,1,2,...,n-1}的子集S { for (int i = 0; i < n; i++) if (s&(1 << i))printf("%d ", i); printf("\n"); } int main() { int n; cin >> n; for (int i = 0; i < (1 << n); i++) print_subset(n, i); return 0; }