笔者最近再做算法题的时候,发现可以通过位运算 | 0 取整去替代parseInt()方法的使用,由此收录了一些位运算优化的使用场景。
位运算符表
1.取整
位运算符只将整数部分转化为二进制,遇到小数时,会自动将小数部分舍去。
以下三种位运算符都能够实现取整的需求,可以通过它们替代Math.floor()或parseInt()
1.1 异或运算取整
13.3 ^ 0 //13
-13.3 ^ 0 //-13
1.2 或运算符取整
12.2 | 0 // 12
-12.2 | 0 // 12
1.3 双否运算取整
~~13.3 // 13
~~-13.3 // -13
1.4 左移运算取整
12.2 << 0 // 12
-12.2 << 0 // -12
2. 判断数组中是否存在某个值
let arr = [5,7,9]
if(~arr.indexOf(7)){//替代indexOf() > -1
console.log('存在')
}
3. 判断奇偶性
if( n % 2) == 01
// n 是个奇数
}else{
// n是偶数
}
4. 交换两个数
异或^的性质:
- 交换律 可以任意交换运算因子的位置,结果不变
- 结合律(即
(a^b)^c = a^(b^c))- 对于任何数x,都有
x^x = 0,x^0 = x- 自反性
A^B^B = A^0 =A
//常规写法
int tmp = x
x = y
y = tmp
//通过异或替代辅助变量
x = x ^ y //
y = x ^ y // y = (x ^ y) ^ y = x ^ y ^ y = x
x = x ^ y // x = (x ^ y) ^ x = x ^ x ^ y = y
5. 找出唯一成对的数
// 1-1000这1000个数放在长度为1001的数组arr中,只有一个数重复出现,请把它找出来
let x1 = 0
for(let i = 0; i < arr.length; i++){
x1 = x1 ^ i // x1 = 1^2^3^...^1000
}
for(let i = 0; i < arr.length; i++){
x1 = x1 ^ arr[i] // x1 = (1^2...^1000)^(1^2^...^k^k^...^1000) = 0^0^...^k = k
}
总结
位运算的奇巧淫技能够在很多算法题中帮助我们更简单地解决问题,简化我们的代码量,提高做题速度!希望本文能够对你有所帮助。