位运算中异或的常见用法总结 | 算法必看知识系列二十五

原文链接

位运算中异或的常见用法总结 | 算法必看知识系列二十五
异或(^) 这个位操作运算符相信大家一定都不陌生,这个运算符可以用来解决很多普通算法解决不了的问题,而且位运算是直接对二进制码做运算,相对普通的加减乘除运算符来说的话更加的高效,我们借着题目一起来看看。

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----

来源 | 五分钟学算法
作者 | 程序员小吴

上一篇:你也被Spring的这个“线程池”坑过吗?


下一篇:慢速排序算法到底有多慢 | 算法必看系列三十三