7.3子集生成

給定一個集合,枚舉所有可能的子集,本節討論的集合中沒有重複元素

7.3.1 增量構造法

第一種思路一次選出一個元素放到集合中

#include<stdio.h>
#include<cstring>
using namespace std;
int A[100];
void print_subset(int n,int* A,int cur){
    for(int i=0;i<cur;i++)
        printf("%d ",A[i]);
    printf("\n");
    int s=cur?A[cur-1]+1:0;
    for(int i=s;i<n;i++){
        A[cur]=i;
        print_subset(n,A,cur+1);
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(A,0,sizeof A);
        print_subset(n,A,0);
    }
    return 0;
}

上面的代碼用到了定序的技巧:規定集合A中所有元素的編號從小到大排列

7.3.2 位向量法

構造一個位向量B[i],而不是直接構造子集A本身,其中B[i]=1,當且僅當i在子集A中

#include<stdio.h>
#include<cstring>
using namespace std;
int B[100];
void print_subset(int n,int* B,int cur){
    if(cur==n){
        for(int i=0;i<cur;i++)
            if(B[i])
                printf("%d ",i);
        printf("\n");
        return;
    }
    B[cur]=1;    //選第cur個元素
    print_subset(n,B,cur+1);
    B[cur]=0;
    print_subset(n,B,cur+1);
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(B,0,sizeof B);
        print_subset(n,B,0);
    }
    return 0;
}

7.3.3 二進制法

爲了處理方便,最右邊的位總是對應元素0,而不是元素1

#include<stdio.h>
#include<cstring>
using namespace std;
int B[100];
void print_subset(int n,int s){
    for(int i=0;i<n;i++)
        if(s&(1<<i)) printf("%d ",i);
    printf("\n");

}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0;i<(1<<n);i++)
            print_subset(n,i);
    }
    return 0;
}


發佈了38 篇原創文章 · 獲贊 2 · 訪問量 8038
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章