0
点赞
收藏
分享

微信扫一扫

暴力枚举之子集枚举

和谐幸福的人生 2022-02-07 阅读 60
c++算法

首先在集合方面要有相应的数学知识,一个集合中含有n个元素那么包括空集在内的子集数是
2^n个,而以下子集枚举中用到的子集数都是包含空集在内
每个集合子集都和某个二进制数有关且是唯一的
举个例子  :假设有集合A={1,2,3,4,5},举例其中四个子集A1={1,3,4,5}、A2={1,4,5}、A3={3}、A4={2,3}
那么按照顺序把全集A的每个元素在它每个子集中是否出现的状况用0(表示在这个子集中没出现)和1(表示在这个子集中出现)表示,每个子集会得到一个专属的二进制数换句话说这个二进制数可以代表某集合中的某个子集

                      A1={1,3,4,5}         A2={1,4,5}             A3={3}                A4={2,3}

A中元素12345二进制
A1的元素出现状况10 1  1 1  11101
A2的元素出现状况1001111001
A3的元素出现状况0010000100
A4的元素出现状况0110000110


                                                       
(二进制转换时是低位在右要反过来,如:全集中表示元素1的二进制位在最右边)   
而我们知道每个二进制是可以转换为唯一一个十进制的,又因为子集个数共为2^n个所以我们总结: 有2^n个十进制数可唯一代表某集合的全部的子集
因此可写成:

A中元素 12345二进制十进制数
A1的元素出现状况101111110129
A2的元素出现状况100111100125
A3的元素出现状况00100001004
A4的元素出现状况01100001106


                                 

而由于空集是包含在2^n里面的,但是空集用0表示所以通常正好用   [0,1<<n)的左开右闭区间来表示全部子集的区间(1<<n是位移运算符表示1 * 2的n次方),全集也可以用U=(1<<n)-1表示
另外上面举例的A集合元素正好是1,2,3,4,5    因为有时我们并不知道集合的元素有哪些,为了更好的表示全集合,我们用第i (1<=i<=n)个来表示A集合的第i个元素(空集正好是0,i=0时为空集,所以是1~n-1)写成1<<(i-1)
以下总结关于集合的相关运算
1.并集
我们用之前的例子举例,A2和A3取并集等于A1所以用到了按位或运算 ,(注意不管是或运算("|")、与运算("&")还是异或运算("^")都是对二进制而言,只有二进制数能用,为了清楚表达,以下二进制转换成的十进制用a表示,A表示集合
a1=a2|a3
2.交集
同样a3=a1&a4
3.包含
A2是A1的子集所以A1并A2等于A1,A1交A2等于A2 (越并越大,越交越小
所以判断A1是否包含A2写成 :(a1|a2==a1)&&(a1&a2==a2)
4.属于
判断某元素是否属于某集合,只需将他的唯一代表十进制与原集合取交集,不是空集(非0)那么就是属于这个集合   , 1<<(3-1)&  a1   判断第三个元素是否属于A1集合

举报

相关推荐

0 条评论