位运算
本文最后更新于:2024年2月12日 晚上
二进制操作
序号 | 操作 | 代码 | |
---|---|---|---|
1 | 计算 i 对于其子集 j 的 补集 | i ^ j | |
2 | 判断 i 是否为 j 的 子集 | ( i \ | j ) == j |
3 | i 去掉指定位置的 1 | ( i & (~( 1 << n ) ) ) | |
4 | 判断 i 和 j 是否有交集 | (i & j) == 0 | |
5 | 移除二进制表示中最右侧的1 Brian Kernighan 算法:$f(x)=x \& (x-1)$ |
x = x & (x - 1) | |
6 | 异或运算^ 可以理解成是不带进位的加法 |
题目:
473. 火柴拼正方形
二进制枚举
常用在求不同的组合的问题中,如:7 选 5 的所有组合,求集合的所有子集
原理:利用数字的「二进制表示」中 1 的位置和个数的不同来确定所有组合。
例如:集合大小为7,则其所有子集共有128个(包括空集),0~128的每一数字的二进制表示代表每种子集,0代表不选该位置的元素,1表示选择。
// 以求大小为7的集合的子集为例
for (int i = 0; i < 1<<7; i++) { // 1<<7 = 128 = 2 ^ 7
for (int j = 0; j < 7; j++) {
if ((i >> j) & 1 == 1) { // 表示选该位置的元素
System.out.print(nums[j] + " ");
}
}
System.out.println();
}
枚举二进制子集
// 枚举二进制子集
for (int i = 1; i <= 5; i++) {
// 枚举出i的所有二进制子集
for (int j = i; j > 0; j = (j - 1) & i) {
System.out.print(j + " ");
}
System.out.println();
}
输出:
1 (01)
2 (10)
3 2 1 (11, 10, 01)
4 (100)
5 4 1 (101, 100, 001)
本文作者: MerickBao
本文链接: https://merickbao.top/post/%E7%AE%97%E6%B3%95/%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/%E4%BD%8D%E8%BF%90%E7%AE%97.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!