`

求集合的所有子集的算法(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);

}

}

分享到:
评论

相关推荐

    输出集合的所有子集

    在IT领域,尤其是在编程与算法设计中,"输出集合的所有子集"是一个常见的问题,它不仅考验了程序员对数据结构的理解,还涉及到了递归、位运算等多种技术的应用。根据给定的文件信息,我们可以深入探讨两个实现方法:...

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

    在计算机科学中,集合子集的问题是一个常见的算法问题,它要求找出给定集合的所有可能子集。本示例将探讨两种解决方法:一种基于回溯的递归策略,另一种则是利用位域映射的技术。 首先,让我们理解集合子集的概念。...

    1.4 求集合的所有子集问题.rar

    在求集合子集问题中,递归算法的基本思想是:对于集合S,其子集可以分为两类:包含当前元素S[i]的子集和不包含当前元素的子集。通过递归调用,我们可以分别生成这两类子集,并将它们合并以得到S的所有子集。 下面是...

    c++子集和程序

    C++子集和程序是一种利用回溯法解决数学问题的编程实践,常见于算法分析与设计的课程实验中。在这个程序中,我们主要探讨的是如何找出一个整数集合的所有可能子集及其和,这是一种典型的组合优化问题。回溯法是一种...

    c++二叉树法求集合幂集

    幂集是指一个集合的所有子集构成的新集合,包括空集和自身。在本例中,我们将探讨如何使用C++通过二叉树法来实现这个功能。 首先,我们需要理解二叉树的概念。二叉树是一种数据结构,每个节点最多有两个子节点,...

    集合的所有子集(源码下载)

    部分内容展示了一段C++代码,它实现了求解集合子集的算法。这段代码首先输入集合的元素个数和元素值,然后通过递归函数`print`来生成并打印子集。`print`函数的工作原理是:对于每个元素,有两种选择,即包含它或不...

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

    在计算机科学领域,子集合问题是一个经典的问题,它涉及到寻找一个集合的所有可能子集,包括空集和集合本身。在给定的标题“子集合问题(c++实现)”中,我们聚焦于使用C++编程语言来解决这个问题。描述指出,程序通过...

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

    总之,交错幂集是集合的子集的一种独特组合,通过递归算法可以在C++中有效地计算出来。在给定的代码中,`computePermutations`函数通过递归调用来生成指定长度的交错幂集,从而展示了解决这类问题的思路。

    算法(c++)—— 集合划分问题.rar

    本压缩包文件“算法(c++)—— 集合划分问题.rar”可能包含了一个关于如何用C++解决集合划分问题的实例或教程。 集合划分问题描述为:给定一个无序的元素集合,目标是将这些元素划分为若干个非空子集,使得每个...

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

    该问题的基本形式是:给定一个正整数集合\( S=\{x_1,x_2,…,x_n\} \)和一个正整数\( c \),询问是否存在集合\( S \)的一个子集\( S_1 \),使得该子集中所有元素的和等于\( c \)。 #### 输入格式 输入的第一行包含两...

    输出n个整数的所有子集

    在C++编程中,"输出n个整数的所有子集"是一个常见的数据结构与算法问题。这个问题涉及到集合论和位运算,是理解计算机科学中基本概念的一个好练习。在这个实验一中,我们的目标是设计一个程序,它能够接收n个整数...

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

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

    RANSAC 算法C++实现

    RANSAC算法的基本思想是通过反复选取随机子集来估计模型,并比较子集内数据点的一致性,从而找出最能代表数据集主要模式的模型。 在C++实现RANSAC算法时,首先需要理解其核心步骤: 1. **初始化**:设定阈值...

    子集生成的三种方法.rar

    本资源"子集生成的三种方法.rar"包含使用C++编程语言实现的三种不同的子集生成算法:回溯法、递归以及动态规划。接下来,我们将详细探讨这些方法。 首先,回溯法是一种通过试探性地解决问题并适时“回退”以寻找...

    C++实现FP-Growth算法

    Apriori算法基于“频繁项集的任何子集也必须是频繁的”这一先验性质,通过迭代生成候选集并检查其支持度来找到频繁项集。然而,这种方法在处理大数据时效率较低,因为它会产生大量的中间结果。 结合C++的FP-Growth...

    C++实现生成组合算法

    在计算机科学和数学中,组合算法是一种常用的算法,用于生成所有可能的组合或子集。下面是 C++ 实现生成组合算法的详细介绍。 一、组合的基本概念 组合是指从一个集合中选出若干元素,按照一定的顺序排列起来的...

    子集树问题c++试设计一个用回溯法搜索子集空间树的函数。

    在装载问题中,每个节点代表一个装载方案,根节点表示空集合,叶子节点表示所有可能的装载组合。回溯法则是在这棵树中进行深度优先搜索的过程。 #### 四、代码分析 根据给定的部分内容,我们可以进一步解析其关键...

    求子集c++算法,经典

    对于给定的一组元素集合,我们需要找到该集合的所有可能子集。例如,给定一个集合`{1, 2, 3}`,它的所有子集为`{},{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3}`。 #### 二、代码解析 根据提供的代码片段,我们可以看到...

    C++算法代码实例

    例如,寻找一个集合的所有子集或遍历一个图形的所有路径。 2. **递归(Recursion)**:递归是函数或过程调用自身的技术,常用于分治策略和树形结构的处理。例如,计算阶乘、斐波那契数列等。 3. **回溯...

Global site tag (gtag.js) - Google Analytics