生成子集 (增量構造法)
阿新 • • 發佈:2017-07-11
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[16View Code]; 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; }
生成子集 (增量構造法)