子集生成的各种实现

/*子集生成的各种实现*/
#include <iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
#define maxn 26000
int A[maxn];
int B[maxn];
int n,sum;
void print_subset(int n,int *A, int cur)//用增量法实现子集生成
{
    int i;
    for(i=0; i < cur ; i++)
    {
        printf("%d ",A[i]);//打印当前集合
        if(i==0)
            sum++;//没有把空集列出来,共2^n-1个
    }
    printf("\n");
    int s = cur ?A[cur-1]+1 : 0;//确定当前元素最小可能值
    for(i=s; i<n; i++)
    {
        A[cur]=i;
        printf("cur = %d i = %d\n",cur,i);
        printf("调用print_subset( %d )\n",cur+1);
        print_subset(n,A,cur+1);//递归构造子集

    }
}
void print_subset1(int n,int *B,int cur)//用位向量法实现子集生成
{
    printf("cur = %d n = %d\n",cur,n);
    if(cur==n)
    {
        for(int i=0; i<cur; i++)
            if(B[i])
                printf("%d ",i);//打印当前集合
        sum++;//共有2^n个
        printf("\n");
        return ;
    }
    B[cur]=1;
    print_subset1(n,B,cur+1);//选第cur个元素
    B[cur]=0;
    print_subset1(n,B,cur+1);//不选第cur个元素
}
//二进制法
//当用二进制表示子集时,位运算中的按位与、或、异或对应集合的交、并、和对称差
void print_subset2(int n,int s)//打印{0,1,2,3,...,n-1}的子集S
{
    for(int i=0; i<n; i++)
        if(s&(1<<i))
            printf("%d ",i);
    printf("\ns = %d",s);
    printf("\n");
}
int main()
{
    while(~scanf("%d",&n))
    {
        sum=0;
        //print_subset(n,A,0);
        //print_subset1(n,B,0);
        //printf("sum = %d\n",sum);
        for(int i=0; i<(1<<n); i++)//枚举各子集所对应的编码0,1,2,3,...,2^n-1
            print_subset2(n,i);
        printf("sum = %d\n",1<<n);
    }
    return 0;
}

 

 

posted @ 2013-07-21 18:47  myth_HG  阅读(350)  评论(0编辑  收藏  举报