您的位置:首页 > 其它

子集生成的三种方法

2016-10-15 11:19 246 查看

子集生成的三种方法



最近遇到一个子集生成的题  没有很快的写出来  所以在把之前的过的子集生成方法在复习一边

第一种  增量构造法

在lrj紫书中  这是放到第一个讲解的 。。。。。。

顾名思义 增量构造法 就是按照递增顺序就行构造子集 防止子集的重复 如 集合{1,2} 就不会输出{1,2} 和{2,1}这样重复的子集了 在解答书中生成
2^n方个子集

直接看代码吧

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF 300
int A[100];
void print_subset(int n,int *A,int cur)
{
for(int i=0;i<cur;i++)
printf("%d ",A[i]);//输出子集 当前的集合
printf("\n");
int s=cur?A[cur-1]+1:0;//确定当前最小的可能值  如果这里不是 这里特殊的就是cur==0时 其他的就是选比前一个大1的
for(int i=s;i<n;i++)
{
A[cur]=i;//将i加入当前的集合
print_subset(n,A,cur+1);// 递归构造子集
}
}
int main()
{
int n;scanf("%d",&n);
print_subset(n,A,0);
}
第二种 位向量法

这个就不多数了 最简单的 就i是选与不选 代码比较好些 容易理解 但是解答树节点是 2^n+1-1 比上面的大一倍

容易处理他给出的集合

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF 300
int B[100];
void print_subset(int n,int *B,int cur)
{
if(cur==n)
{
for(int i=0;i<cur;i++)
if(B[i])printf("%d ",i);
printf("\n");
return ;
}
B[cur]=1;
print_subset(n,B,cur+1);//选
B[cur]=0;
print_subset(n,B,cur+1);//不选
}
int main()
{
int n;scanf("%d",&n);
print_subset(n,B,0);
}


第三种 也是应用最广的一种 这种思想在很多地方都能用到 非常好用 二进制法

简单的说就是二进制的每一位代表一个数 

   A              B             A&B          A|B         A^B

10110      01100        00100       11110      11010

 {1,2,4}                {2,3}                       {2}                  {1,2,3,4}            {1,3,4}

可以看出分别对应 交 并 差 全集是 n个1 就是2^n-1  all_set=(1<<n)-1 则A的补集是all_set^A

 上代码吧

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF 300
int B[100];
void print_subset(int n,int s)
{
for(int i=0;i<n;i++)
if(s&(1<<i))printf("%d ",i);
printf("%n");
}
int main()
{
int n;scanf("%d",&n);
for(int i=0;i<(1<<n);i++)
print_subset(n,i);
}
下面是一些集合的操作 

空集                            s=0

只含有第i个元素                                         1<<i

含有全部n个元素                                        (1<<n)-1

判断第i个元素是否属于集合S                        S>>i &1

向集合中加入第i个元素                                 s|=1<<i

从集合中去除元素i                                         s&~(1<<i)

集合S和集合T的并集                                      S|T

集合S和集合T的交集                                       S&T



 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: