失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 回溯法经典算法 求集合中所有的子集

回溯法经典算法 求集合中所有的子集

时间:2019-02-03 18:13:43

相关推荐

回溯法经典算法 求集合中所有的子集

今天我们来看一下子集的问题。

题目描述:给定一个任意集合A,集合的长度为Length,让你打印出这个集合中所包含的所有子集。

题目分析:此问题实际上也是一个遍历树的问题,进行遍历每一个子元素,再进入下层函数时候记录上层结果,加入到下层函数中,再存储起来。其实总结器来他就是一颗完全二叉树。以下我们结合图来具体的说一下:

我们以集合{1,2,3}来对此画树状图理解一下。图如下:

以此我们可以得到集合{1,2,3}中的子集有{},{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3};

以此我们就可以用递归算法对其进行代码操作。

具体的递归方法:对于一个含有n个元素的集合,我们要对其进行找子集,首先我们需要先定义一个数组,以此来存储对这N位的2进制数来表示这个集合,第i为如果为1则表示第i个元素在表示的这个集合中,否则则不再这个集合中。简单的来说就是首先我们先让这个数组的第一个元素为No,然后他会一直往下找,如果到递归结束时还是No,就将它打印出来,然后进行回溯到上一层。然后我们就把这个元素定位Yes,然后在进行在Yes条件下进行递归寻找,我们每次进行到递归结束的条件时,我们对其进行回溯。可能我说的还是有点理解不了,大家可以结合着上面的图来看代码:

#include<stdio.h>#include<string.h>#include<assert.h>int arr[]={0};//存储当前第i个位置元素包含还是不包含void Ziji(char brr[],int k,int length)//k是递归的层次,k与集合的长度有关{assert(arr!=NULL); if(k==length)//递归结束的条件{printf("{ ");for(int i=0;i<length;i++){if(arr[i]==1){printf("%c ",brr[i]);}}printf("}");printf("\n"); }else{arr[k]=0;//集合中的第i个元素没有包含,也就是(No)Ziji(brr,k+1,length); //进行没有被包含(No)的递归arr[k]=1;//集合中的第i个元素被包含(Yes)Ziji(brr,k+1,length);//然后进行被包含下(Yes)的递归} }int main(){char str[]="ABC";int lenth=strlen(str);Ziji(str,0,lenth);return 0;}

综上所述呢,我们可以得到一个含有N个元素的集合,它的所有子集的个数为N!个。

大家现在结合着代码是不是理解了此算法的递归操作呢?

如果没理解我再给大家讲一下非递归的算法,我觉得这种办法挺好运的,这种办法就是用C++中的位运算符来进行操作的,上面我们可以得出一个含有N个元素的集合,它的所有子集的个数为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)

根据以上规律我们可以得出拿一个整形值与一个数进行&操作可以得到我们所需要的子集。进行再一步的观察我们可以看出这个数就是1,每次进行&之后,让这个数进行左移(<<)i位,这个i的初始为0,结束为N,所以我们就可以求出我们所需要的结果,具体代码如下:

#include<stdio.h>#include<assert.h>#include<string.h>int main(){char arr[]="ABC";int a=strlen(arr);int thm=1<<a;//含有N个元素的子集共有N!个for(int i=0;i<thm;i++){for(int j=0;j<a;j++)if(i&1<<j)//每次要对其进行左移操作,然后又i进行&{printf("%c",arr[j]);}printf("\n");}return 0;}

以上的内容就是我对一个集合中求子集问题的所有理解,希望它可以帮助大家。如有错误,请大家评论指正。

如果觉得《回溯法经典算法 求集合中所有的子集》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。