闲着没事干可以做做
可以看到,那个函数直接return了,也就是说,得找到一个表达式,直接求出结果
简单分析一下:
其第i位为1当且仅当n的右边i位均为1
也就是说,前i-1位有0,第i位就是0
也就是说,找到n的第一个出现的0的位置,返回这个位置前面都为1的数字就可以了
先给出答案:
((n + 1) & (~n)) - 1
完整的代码看一下:
#include <iostream>
using namespace std;
int bitManipulation4(int n) {
return
((n + 1) & (~n)) - 1
;
}
int main() {
int t, n;
cin >> t;
while (t--) {
cin >> n;
cout << bitManipulation4(n) << endl;
}
return 0;
}
先复习一下按位运算符在集合中的意义吧
设二进制集合A和B
运算符及意义:
与(&)运算符:A&B 计算出A和B的并集
或(|)运算符:A|B 计算出A和B的交集
按位取反(~)运算符:~A 计算出A的补集
异或(^)运算符:A^B 计算出A与B的对称差集
((n + 1) & (~n))
这个就是用来找到找到n的第一个出现的0的位置,并且只有该位置为1的数
减1就是结果
用例子来讲讲:
假设n的二进制为:1011
n + 1 = 1100
~n = 0100
((n + 1) & (~n)) = 0100
((n + 1) & (~n)) - 1 = 0011
二进制的运算在其他地方也可以用到,比如枚举子集
推荐一题:
Mobile Computing - UVA 1354 - Virtual Judge (vjudge.net)
可以用枚举子集的方法从上到下构建二叉树
这题实际上是我上篇博客的主题,但是那篇博客不是用枚举子集的方法来做的