异或(^) 这个位操作运算符相信大家一定都不陌生,这个运算符可以用来解决很多普通算法解决不了的问题,而且位运算是直接对二进制码做运算,相对普通的加减乘除运算符来说的话更加的高效,我们借着题目一起来看看。
01
对两个输入参数做加法运算,但是不能使用 “+” 运算符 。
解法思路
看到这样的问题,能想到的只有位运算,问题是怎么算?相信大家小学刚学习加法的时候,对于一下子不能得到答案的题,肯定会在草稿纸上列竖式,从右向左算,同一列对下来的数字相加如果超过 10,那么肯定要在下面写两个数字相加后的个位数,然后往前进一位,下一位运算时就要加上这个进位,用这样的方式直到最后算出结果。这题的思路也是一样的,只不过有两点不一样,第一,10 进制变成了 2 进制,第二,我们不再是在草稿纸上列竖式,而是要写成计算机看得懂的代码,这就得借助我们的位运算了,因为 2 进制表示的数中只会出现 0 和 1,你可以把这两个数看成是 true 和 false,这样更好理解,我们可以先通过异或塞选出不用进位的情况,然后再用与运算和左移运算计算出进位的情况,迭代更新出最后的结果。
参考代码
public int plus(int a, int b) {
int aTemp = 0, bTemp = 0;
while (b != 0) {
aTemp = a ^ b;
bTemp = (a & b) << 1;
a = aTemp;
b = bTemp;
}
return a;
}
02
如何在不创建临时变量的情况下进行交换两个数?
解法思路
异或的常见应用,很简单,但是注意思考角度从位出发,而不是数,这点很重要。
参考代码
public void swap(int a, int b) {
// a 中存放两数互异的点位
a ^= b;
// 取反 b 中不同于 a 的点位,也就是实现了 b = a
b ^= a;
// 取反 a 中不同于 b 的点位,也就是实现了 a = b
a ^= b;
}
03
如果把 A 转换成 B ,需要改变多少位?
解法思路
异或的简单应用,两个数做异或的结果就是两个数差异所在,然后只需计算这个结果中有多少个 1 即可。
参考代码
public int convertA2B(int A, int B) {
int n = A ^ B;
int count = 0;
while (n != 0) {
// n - 1 是将 n 的最低位为零
n = n & (n - 1);
count++;
}
return count;
}
总结
位运算相对其他的运算来说更加的高效,异或在位运算中的应用非常广,但是这里的难点是我们平时可能会忽视位运算,导致我们遇到一般的问题不会往位运算的方向去想,另外就是如果对二进制的运算不熟,我们也很难理解一些位运算的综合操作,这里提到了异或可以交换两个数,做加法操作,还可以用来解决一些问题。
欢迎你来分享你对异或以及位运算的认识。
----END----
来源 | 五分钟学算法
作者 | 程序员小吴