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

生成子集 (增量構造法)

arr tro 這樣的 結構 print nbsp can alt amp

使用增量構造法可以構造出升序數組arr的不重復子集,並且按字典序排序

技術分享
#include<bits/stdc++.h>
using namespace std;
int arr[16];
inline void print_subset(int *index, int cur, int n)///cur值這裏可以理解為在這個堆棧層子集的集合數
{
    for(int i=0; i<cur; i++) {printf("%d ", arr[index[i]]);} if(cur)puts("");
    int s = cur ? index[cur-1]+1 : 0;///因為index是arr升序序列的下標,這裏cur就是當前arr可能最小值的下標
for(int i=s; i<n; i++){ index[cur] = i; print_subset(index, cur+1, n); } } int main(void) { int n, index[16];///index數組輔助構造,其值為升序序列的下標,註意是從0開始 for(int i=0; i<16; i++) index[i] = i; while(~scanf("%d", &n)){ int cur = 0; for(int i=0; i<n; i++) arr[i] = i+1
;///這裏arr的值為1~n的一個序列 print_subset(index, cur, n); puts(""); } return 0; }
View Code

如果要構造如下這樣的排序的話,以輸入3為例

1
2
3
1 2
1 3
2 3
1 2 3

可以在原有的基礎上使用一個結構體將每個子集的長度和具體序列用int和string存起來就能通過二級排序構造出來了

技術分享
#include<bits/stdc++.h>
using namespace std;
int arr[16];
struct item
{
    int len, digit[16
]; string s; }; bool cmp(const item fir, const item sec) { if(fir.len==sec.len) return fir.s < sec.s; return fir.len < sec.len; } item ans[1<<16]; int top = 0; inline void print_subset(int *index, int cur, int n) { //for(int i=0; i<cur; i++) {printf("%d ", cur);printf("%d ", arr[index[i]]);} puts(""); ans[top].len = cur; stringstream temp; for(int i=0; i<cur; i++){ ans[top].digit[i] = arr[index[i]]; } temp<<ans[top].digit; temp>>ans[top].s; top++; temp.clear(); int s = cur ? index[cur-1]+1 : 0; for(int i=s; i<n; i++){ index[cur] = i; print_subset(index, cur+1, n); } } int main(void) { int n, index[16]; for(int i=0; i<16; i++) index[i] = i; while(~scanf("%d", &n)){ int cur = 0; top = 0; for(int i=0; i<n; i++) arr[i] = i+1; print_subset(index, cur, n); sort(ans, ans+top, cmp); for(int i=0; i<top; i++){ // if(ans[i].len) printf("%d ", ans[i].len); for(int j=0; j<ans[i].len-1; j++){ printf("%d ", ans[i].digit[j]); } printf("%d", ans[i].digit[ans[i].len-1]); puts(""); } puts(""); } return 0; }
View Code

生成子集 (增量構造法)