求子集的三種方式的總結


求自己總共有三種方式:

增量構造

位向量

二進制

首先假設集合A中有n個元素,而且是非重集,一個下標唯一對應一個元素,那么求A的子集就變成了求0~n-1的子集。這個思想對於所有的三種方式都是通用的。

 

第一種增量構造法的思想是,每一次都從0~n-1中挑出一個元素來,每挑一次,就是一個集合。然后再挑元素進入這個集合,但是這次挑選元素的時候,必須比之前的那個元素大。

下面是代碼實現:

//假設后一個非可重集合P,里面的元素各不相同,現在要從中挑選出它的所有子集來
//這個問題可以轉換成挑選出P數組的下標的所有子集。即若P中有n個元素,那么就挑選出0~n-1之間的所有子集來
//以上的分析適合於所有的子集生成算法
//增量構造法的本質是這樣的,每次從0~n-1 中挑選出一個元素來,每挑選一次,就是一個子集。然后再給這個已經挑選出來的子集中挑選元素,這次挑選出來的元素
//必須比之前的元素要大
#include<cstdio>
using namespace std;

const int maxn = 100 + 10;
int ans[maxn];
int n;

void print_sub_set(int cur)
{
    for(int i = 0; i < cur; i++)
    {
        printf("%d ",ans[i]);
    }
    printf("\n");
    int s = cur ? ans[cur - 1] + 1 : 0;
    for(int i = s;i < n; i++)
    {
        ans[cur] = i;
        print_sub_set(cur +1);
    }
}

int main()
{
    n = 3;
    print_sub_set(0);
    return 0;
}

第二種方式是位向量法,如上一種方式所述,問題已經被轉換成求0~n-1的子集,這時再轉換一次,轉換為求一個長度位n位的向量B[i],當b[i]為1時,代表i在這個集合中。在實現的時候,采用了遞歸的思想,每次都決定每一位的歸屬。

下面是代碼實現:

//在上一篇說過,問題轉換成了枚舉0~n-1之間的所有的子集
//在位向量法中,還需要再次去轉換,即將問題轉換為構造一個有n位的向量,當b[i]為1的時候,表示i-1在此集合中,即元素A[i - 1]在集合中
#include<cstdio>
using namespace std;
const int maxn = 100 + 10;
int B[maxn];
int n;

void print_subset(int cur)
{
    if(cur == n)
    {
        for(int i = 0;i < n;i++)
        {
            if(B[i])
                printf("%d ",i);
        }
        printf("\n");
    }
    else
        for(int i = 0; i <= 1; i++)
    {
        B[cur] = i;
        print_subset(cur + 1);
    }

}

int main()
{
    n = 3;
    print_subset(0);
    return 0;
}

最后是二進制法,二進制法的本質和位向量法是一致的,只不過位向量法中的向量B[],變成了一個整數轉換為二進制時有n位的整數,這樣就可以從0枚舉到1<<n - 1,然后再去依次判斷各個位的情況

下面附上代碼:需要注意的一點就是如何判斷各位的情況,就是x&1<<i       

//二進制法的本質和位向量法是一致的,都是構造一組向量
//但是二進制法使用的是位運算的方式
#include<cstdio>
using namespace std;

int n;
//const int ALL_BITS = 1<<n - 1;

void print_subset(int x)
{
    for(int i = 0; i < n;i++)
    {
        if(x & (1 << i))
        {
            printf("%d ",i);
        }
    }
    printf("\n");
}

int main()
{
    n = 3;
    for(int i = 0;i < 1<<n;i++)
    {
        print_subset(i);
    }
    return 0;

}

經過比較這三種方式的效率,增量構造的效率最高,二進制次之,位向量最慢

當輸入達到26的時候,增量構造法11s,二進制15s,位向量20s

但是編程的復雜度而言二進制最簡單,增量構造和位向量一致

&符號代表所有的位一起與。

 


免責聲明!

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



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