`

求集合的所有子集的算法(C++)

阅读更多

 

求集合的所有子集的算法

对于任意集合A,元素个数为n(空集n=0),其所有子集的个数为2^n个

如集合A={a,b,c},其子集个数为8;对于任意一个元素,在每个子集中,

要么存在,要么不存在,对应关系是:

a->1或a->0

b->1或b->0

c->1或c->0

映射为子集:

(a,b,c)

(1,1,1)->(a,b,c)

(1,1,0)->(a,b   )

(1,0,1)->(a,   c)

(1,0,0)->(a      )

(0,1,1)->(   b,c)

(0,1,0)->(   b   )

(0,0,1)->(      c)

(0,0,0)->@ (@表示空集)

算法(1):

观察以上规律,与计算机中数据存储方式相似,故可以通过一个整型数(int)与

集合映射000...000 ~ 111...111(0表示有,1表示无,反之亦可),通过该整型数

逐次增1可遍历获取所有的数,即获取集合的相应子集。

在这里提一下,使用这种方式映射集合,在进行集合运算时,相当简便,如

交运算对应按位与&,{a,b,c}交{a,b}得{a,b}<--->111&110==110

并运算对应按位或|,

差运算对应&~。

算法(2):

设函数f(n)=2^n (n>=0),有如下递推关系f(n)=2*f(n-1)=2*(2*f(n-2))

由此可知,求集合子集的算法可以用递归的方式实现,对于每个元素用一个映射列表marks,标记其

在子集中的有无

很显然,在集合元素个数少的情况下,算法(1)优于算法(2),因为只需通过加法运算,便能映射

出子集,而算法(2)要递归调用函数,速度稍慢。但算法(1)有一个严重缺陷,集合的个数不能大于在

计算机中一个整型数的位数,一般计算机中整型数的为32位。对于算法(2)就没这样限制。

-----------------------------------------------------------------------------------------

算法(1,取低位到高位码段作为映射列表

template<class T>

void print(T a[],int mark,int length)

{

bool allZero=true;

int limit=1<<length;

for(int i=0;i<length;++i)

{

if(((1<<i)&mark)!=0) //mark第i+1位为1,表示取该元素

{

allZero=false;

cout<<a[i]<<" ";

}

}

if(allZero==true)

{

cout<<"@";

}

cout<<endl;

}

template<class T>

void subset(T a[],int length)

{

if(length>31) return;

int lowFlag=0; //对应000...000

int highFlag=(1<<length)-1; //对应111...111

for(int i=lowFlag;i<=highFlag;++i)

{

print(a,i,length);

}

}

-----------------------------------------------------------------------------------------

算法(2)

template<class T>

void print(T a[],bool marks[],int length)

{

bool allFalse=true;

for(int i=0;i<length;++i)

{

if(marks[i]==true)

{

allfalse=false;

cout<<a[i]<<"  ";

}

}

if(allFalse==true)

{

cout<<"@";

}

cout<<endl;

}

template<class T>

void subset(T a[],bool marks[],int m,int n,int length)

{

if(m>n)

{

print(a,marks,length);

}

else

{

marks[m]=true;

subset(a,marks,m+1,n,length);

marks[m]=false;

subset(a,marks,m+1,n,length);

}

}

分享到:
评论

相关推荐

    求一个集合子集的算法示例

    求一个集合子集的算法示例, 用两种方法解,一种是基于回溯的递归求解,一种基于位域映射.

    算法设计与分析-子集和问题

    子集和问题的一个实例为〈S,c〉。其中,S={x1,x2,…,xn}是一个正整数的集合,c是一个正整数。子集和问题判定是否存在S的一个子集S1,使得 ∑x=c, (其中x∈S1)。试设计一个解子集和问题的方法。你可以假设处理范围...

    C经典算法之m元素集合的n个元素子集

    假设有个集合拥有m个元素,任意的从集合中取出n个元素,则这n个元素所形成的可能子集有那些?

    子集和问题

    对S集合子集树采用深度优先的顺序进行搜索,子集树从上到下每层标示着S集合中每个从左到右元素“选”或者“不选”(左1右0)。 试着用回溯算法设计解子集和问题。 输入格式 第一行2个数:正整数n和整数c。n...

    C++实现的密度聚类的算法.cpp

    定义**当前处理集合**,并复制**样本集合**所有点。 定义**上一步处理集合**,并复制**样本集合**所有点。 定义**处理列表** 当**当前处理集合**非空时,**开始外循环** 取出**核心点集合**中的第一个点(顺序随便...

    回溯算法 子集和数

    在一个集合A[1~n]中找出所有元素之和等于S的子集。 ①确定解向量:X[1~n], X[i]=1表示A[i]被选入子集,X[i]=0表示弃选,本质:划分成2个子集。②解空间树

    5-1+_子集和问题_

    对于给定的正整数的集合 S={x1,x2,…,xn }S={x1,x2,…,xn }和正整数 c,编程计算 S 的一个子集S1,使得∑x∈S1x=c ∑x∈S1x=c。数据输入:第 1 行有 2 个正整数 n 和 c,n 表示 S 的大小,c是子集和的目标值。...

    C++使用递归算法求交错幂集

    交错幂集是一种数学概念,它是由集合的所有子集的交错和构成的集合。具体来说,对于一个集合S,其交错幂集P(S)定义为:P(S) = {x ∈ S^n | x1 ≠ x2, 当 1 ≤ i ≤ n},其中S^n表示S的所有n元子集的集合。 该代码...

    子集合问题(c++实现)

    本程序针对“子集和问题”构造了一棵n叉树,采用深度优先算法,实现了对此n叉树的非递归遍历。 下载包中附求解问题算法的伪代码、图、源程序等等。

    算法Prim.zip

    意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小。该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník...

    c++标准程序库+超越c++标准程序库--高清

    C++中的标准程序库是类库和函数的集合,其使用核心语言写成。标准程序库提供若干泛型容器、函数...标准模板程序库是C++标准程序库的子集,包含容器、算法、迭代器、函数对象等。也有些人使用术语STL代表C++标准程序库。

    C++ 标准库中文和英文版

    C++中的标准程序库是类库和函数的集合,其使用核心语言...标准模板程序库是C++标准程序库的子集,包含容器、算法、迭代器、函数对象等。也有些人使用术语STL代表C++标准程序库。 使用C++标准程序库时,不必加上“.h”。

    二分图最大匹配算法

    二分图指的是这样一种图,其所有顶点可以分成两个集合X和Y,其中X或Y中任意两个在同一集合中的点都不相连,所有的边关联在两个顶点中,恰好一个属于集合X,另一个属于集合Y。给定一个二分图G,M为G边集的一个子集...

    C++标准程序库

    C++中的标准程序库是类库和函数的集合,其使用核心语言...标准模板程序库是C++标准程序库的子集,包含容器、算法、迭代器、函数对象等。也有些人使用术语STL代表C++标准程序库。 使用C++标准程序库时,不必加上“.h”。

    算法导论(part1)

    书中的算法以英语加伪代码的形式给出,只要有一点程序设计经验的人都能读懂,并可以用任何计算机语言(如C/C++和Java等)方便地实现。在书中,作者将算法的讨论集中在一些比较现代的例子上,它们来自分子生物学(如...

    模拟退火算法解决0-1背包问题的实现

    背包问题,是指从n件不同价值、不同重量物品中按一定的要求选取一...其形式化描述如下:给定一个物品集合s={1,2,…,n},物品i具有重量 和价值 。背包能承受的最大载重量不超过W。背包问题就是找到一个物品子集 ,使得

    88.cpp,设计算法判断单循环链表是否每个结点的值都是偶数

    设计算法判断单循环链表是否每个结点的值都是偶数,建立链表,判断,显示。 对任意输入的一组数据,...用递增有序的链表A、B表示两个集合,设计算法求它们的并集。 设计算法判断单循环链表是否每个结点的值都是偶数。

    算法导论(part2)

    书中的算法以英语加伪代码的形式给出,只要有一点程序设计经验的人都能读懂,并可以用任何计算机语言(如C/C++和Java等)方便地实现。在书中,作者将算法的讨论集中在一些比较现代的例子上,它们来自分子生物学(如...

    C++程序标准库自修教程与参考手册简体中文版

    C++中的标准程序库是类库和函数的集合,其使用核心语言写成。标准程序库提供若干泛型容器、函数...标准模板程序库是C++标准程序库的子集,包含容器、算法、迭代器、函数对象等。也有些人使用术语STL代表C++标准程序库。

Global site tag (gtag.js) - Google Analytics