码迷,mamicode.com
首页 > 其他好文 > 详细

生成子集 (增量构造法)

时间:2017-07-11 21:15:16      阅读:374      评论:0      收藏:0      [点我收藏+]

标签:数组   clu   inline   合数   ros   并且   names   soft   using   

使用增量构造法可以构造出升序数组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

 

生成子集 (增量构造法)

标签:数组   clu   inline   合数   ros   并且   names   soft   using   

原文地址:http://www.cnblogs.com/Rubbishes/p/7152331.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!