1. 程式人生 > >構造增量法生成子集

構造增量法生成子集

amp 顯式 字典序 == sin 分析 cnblogs false !=

題意:

生成 1~n 集合的子集, 先按元素從小到大再按字典序排列輸出

分析:

所謂構造增量法, 就是每次都輸出當前數組的元素, 然後再給當前數組最大元素一個增量, 看是否仍然在集合內, 如果在就把他繼續放進數組, 輸出。 這種方法不需要顯式確認遞歸邊界, 如果無法添加元素, 自然就不會再遞歸了。 數據結構我選用了string , 因為字典序比較容易排序出來。

#include <bits/stdc++.h>
using namespace std;
string ans[1 << 15  + 5];
int A[10];
int cnt = 0;
void print_subset(int
n, int* A, int cur){ for(int i = 0; i < cur; i++) { ans[cnt] += A[i] + 0; } cnt++; int s = cur ? A[cur-1] + 1 : 1;// 確定已選元素的最大可能值 for(int i = s; i <= n; i++){ A[cur] = i; print_subset(n, A, cur + 1); // 遞歸構造子集 } } bool cmp(string a, string b){
if(a.size() < b.size()) return true; else if(a.size() == b.size()){ return a < b; } else return false; } int main() { int n; while(scanf("%d", &n) != EOF){ cnt = 0; print_subset(n, A, 0); sort(ans, ans + cnt, cmp); cout << 0 <<endl;
for(int i = 1; i < cnt; i++){ cout << ans[i].size() <<" " << ans[i][0] - 0; for(int j = 1; j < ans[i].size(); j++){ cout <<" " << ans[i][j] - 0; } ans[i] = ""; cout << "\n"; } printf("\n"); } return 0; }

構造增量法生成子集