如果错误或不周,请指教谅解,感谢你的观看
前导
灵感来源:力扣周赛413的第3题
注:需要对二进制,位运算有一定的知识储备
1 集合的储存
对于一个集合S,我们如何表明某些元素存在于该集合中,某些元素不在集合中呢
思路:可以用二进制的形式表示集合S的数字存储
比如二进制 11010 表示元素 1 3 4 都在该集合中 ,其它都不存在
图示:
各个位的二进制表示 | 1 | 1 | 0 | 1 | 0 |
---|---|---|---|---|---|
2的次方 | | | | | |
元素 | 4 | 3 | 不存在 | 1 | 不存在 |
同样的二进制 10101100 表示元素 2 3 5 7 都在该集合中 ,其它元素都不存在,其实集合S代表一个数字,但它却反应了集合与元素的关系
2 集合的操作
1 将元素放入到集合中去
int n;
cin >> n;
int s = 0;
for (int i = 0; i <= n; i++)
s = s | (1 << i); // 把i压入s的集合中
2 将元素从集合中去除
int s = 218; // 二进制表示11011010 集合S包含元素1 3 4 6 7
// 去除3
int p = (1 << 3);
s = s ^ p;
cout << s; // s等于210 二进制表示11010010
// 去除1
p = (1 << 1);
s = s ^ p;
cout << s; // s等于208 二进制表示11010000
3 判断元素是否在集合中,若不在便加入到集合中去
int s = 218; // 二进制表示11011010 S包含元素1 3 4 6 7
int n = 7;
for (int i = 0; i <= n; i++)
{
if ((s >> i & 1) == 0)
s |= 1 << i;
// 说明i不在S的集合中 则加入其中
}
// s=255 二进制表示11111111 S包含元素0 1 2 3 4 5 6 7
4 对于两个集合S,T ,将T中的所有元素放入到集合S中去
int S = 218, T = 45; // 二进制分别表示11011010 101101
// S包含元素1 3 4 6 7 T包含元素0 2 3 5
// 要将T中的0 2 5放入到集合S中去
for (int i = T, b; i; i ^= b)
{ // 从后往前不断取集合T中的元素
b = i & -i; // b代表取出来的元素
if ((S & b) == 0)
S |= b; // 说明b不在S的集合中 则加入其中
}
cout << S;
// S=255 二进制表示11111111 S包含元素0 1 2 3 4 5 6 7
5 求集合S的所有子集
int S = 45; // 二进制分别表示101101 包含元素0 2 3 5
for (int i = S; i; i = (i - 1) & S)
cout << i << " ";
// i表示S的子集
3 总结
不难发现对于任意两个集合S T;S|T、S&T、S^T 分别表示集合的并,交和对称差
再次感谢观看!!!