位运算

252 阅读2分钟

平时的工作中,我想很少有人有用到位运算的,但位运算有些时候真的是很方便很便捷。据两个例子

两个数进行交换


int a = 5;
int b = 9;

一般我们怎么去进行交换呢?申请临时变量

int temp = a;
a = b;
b = temp;

那么用位运算怎么做?进行三次异或操作即可。

a = a ^ b;
b = a ^ b;
a = a ^ b;

交换的原理如下图:

a = a ^ b = 5 ^ 9

b = a ^ b 这个时候把上边的a的结果带入 b = 5 ^ 9 ^ 9 异或的计算是相同为0,不同为1,因此 b = 5

a = a ^ b 这个时候把上边a和b的结果带入 a = 5 ^ 9 ^ 5 = 9

这样就交换完了

Untitled-2022-05-15-1535.png

一个数组中有一种数出现了奇数次,其他出现了偶数次,怎么找到并打印这种数

int[] arr = {4,4,4,3,3,3,3,2,2,1,1};

怎么把里面出现奇数次的 4 找出来? 我们常用的方式首先通过map进行存储并统计每个数出现的次数,最后找出出现奇数次的数即可,如下:

Map<Integer,Integer> two = new HashMap<>();
for (int i : arr) {
    Integer count = two.get(i);
    if (count == null){
        count = 0;
    }
    two.put(i,count + 1);
}

for(Map.Entry<Integer,Integer> entry : two.entrySet()){
    Integer key = entry.getKey();
    Integer value = entry.getValue();
    if (value % 2 != 0){
        System.out.println(key);
        break;
    }
}

那么用位运算就简单了,首先定义一个为0的常量,依次和数组中的每个数进行异或操作,最终得到结果就是出现奇数次的那个数,为什么?因为0和任何数进行异或得到的都是任何数的值,出现偶数次的值因为相同运算后就变成了0,如下:

int eor = 0;
for (int i : arr) {
    eor = eor ^ i;
}

当然,虽然位运算看起来简单,但是对于不常用的人来说多少还是有些看不懂的, 一定程度上降低了代码的可读性。看个人习惯以及对系统的影响。各抒己见。