1. 程式人生 > >枚舉非空真子集

枚舉非空真子集

main std 一次 cin 二進制 兩種 clas stream ret

第一種情況給定的集合是滿狀態的,也就是枚舉2的n次方種狀態下的每一種子集的情況。

for(int x=0;x<(1<<n);x++)

這裏的x是一個二進制數,其長度為n,取值為00000...00000~11111...11111的每一種狀態。

for(int i=0;i<n;i++)
        if(x&(1<<i))

這裏的i的取值為1,10,100,1000,10000...其目的就是一個一個去試x中對應位置的元素是1還是0,如果是1表示當前集合中有這個元素,否則沒有。

第二種情況給定的集合不一定是滿狀態的,這時要輸入一個全集s。

for(int x=s;x;x=s&(x-1
))

這裏的x就是s的子集的一種情況了,後面的i還是類似簽名的道理,一位一位地去試有沒有當前這個元素。

完整實現如下,首先輸入全集元素個數n,進行一次枚舉,接下來輸入給定集合s進行子集的枚舉,這是兩種枚舉情況的舉例。

#include<iostream>
using namespace std;
int n,s;
int main()
{
    cin>>n;
    for(int x=0;x<(1<<n);x++)
    {
        for(int i=0;i<n;i++)
        if(x&(1<<i))
            cout
<<i+1<<" "; cout<<endl; } cin>>s; for(int x=s;x;x=s&(x-1)) { for(int i=0;i<n;i++) if(x&(1<<i)) cout<<i+1<<" "; cout<<endl; } return 0; }

枚舉非空真子集