關於二進制枚舉


算是徹底搞懂二進制枚舉吧。

首先一個集合的子集有2^n個,所以我們枚舉的個數有(1<<n)個;

所以

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

我們知道二進制枚舉的過程如下:

每個位置值為1則保留,不為1則舍棄 ;

設s=13(二進制為1101)那么我們保留0 2 3位置上的數值;

那么我們如何找到每個位置上的數值呢?

我們遍歷的是二進制的十進制表示(比如13),我們當然可以轉化為二進制在枚舉每一位,但是,這很麻煩;

一個很巧妙的方式就是利用位運算;

1<<0=1(0);

1<<1=2(10);

1<<2=4(100);

1<<3=8(1000);

1<<4=16(10000);

...

1<<7=128(10000000);

...

看出來了吧!我們只需要將13&(1<<i)我們便可以得到每一位是不是1 (1<<i除了那一位,剩余的都是0,所以我么就可以得到那一位是不是1)

因此,我們便有了:

for(int i=0; i<n; i++)
        if(s&(1<<i))
            printf(" %d ",a[i]);

完整代碼:

for(int i=0; i<(1<<n); i++)
    {
        for(int i=0; i<n; i++)
        {
            if(s&(1<<i))
                printf(" %d ",a[i]);
        }
    }

這只是將子集輸出,你也可以將枚舉出的子集存到數組或容器(vector等)里,以便他用;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM