参考:https://mp.weixin.qq.com/s/o3pEkayhuMXkl9fp1wA0XA
文章目录
简述
所有数在计算机内存中都是以二进制的形式存储,位运算是直接对二进制位进行操作,因此处理速度上具有优势。当然,如果计算机的计算效率非常之快,二进制运算的优势并非很抢眼,但是位运算有一些经典应用,还可以用位运算优化程序。下面一起来看看吧:
位运算的计算规则和使用示例
计算规则:
(1)and运算
通常用于二进制取位操作,例如一个数与 1相与的结果就是取二进制的最末位,可以用来判断一个整数的奇偶,二进制的最末位为0表示该数为偶数,最末位为1表示该数为奇数。
(2)or运算
通常用于二进制特定位上的无条件赋值,例如一个数与1相或的结果就是把二进制最末位强行变成1。
(3)xor运算
相同取0,不同取1,通常用于对二进制的特定一位进行取反操作,两次异或同一个数最后结果不变,即(a xor b) xor b = a。
(4)not运算
把内存中的0和1全部取反。使用not运算时要格外小心,需要注意整数类型有没有符号,若是无符号整数,那么得到的值就是它与该类型上界的差。
(5)位移运算
左移动1位,各位数计算都会乘以2;右移1位,各位数计算都会除以2。x<<N,x乘以2的N次方;x>>N, x除以2的N次方。
使用示例:
(1)判断奇偶
a&1 等于0 ,a为偶数;等于1,a为奇数。
(2)判断正负数
int b = a>>31 , b=0 则为正,b=1则为负。
(3)取int a的第k位
a >> k & 1。
(4)取相反数
a的相反数 ~a+1。
(5)不用中间变量交换两个数值
void swap(int a, int b){
a ^= b;
b ^= a;
a ^= b;
}
(6)取绝对值
int abs(int a){
int b;
a = b >> 31;
return (a ^ b) - b;
}
实例解析
题目1:只出现一次的数字
题目描述:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
解题思路:对位运算符的应用。
(1)交换律:a ^ b ^ c <=> a ^ c ^ b
(2)任何数与0异或为任何数:0 ^ n => n
(3)相同的数异或为0:n ^ n => 0
注:下面代码可左右滑动查看
class Solution {
public int singleNumber(int[] nums) {
int res = 0;
for(int i = 0; i < nums.length; i++){
res ^= nums[i];
}
return res;
}
}
题目2:二进制数1的个数
题目描述:写一个函数操作无符号整数,返回整数的二进制数1的个数
示例 1:
输入: 00000000000000000000000000001011
输出: 3
解释:输入的二进制串00000000000000000000000000001011 中,共三位为 ‘1’
示例 2:
输入: 00000000000000000000000010000000
输出: 1
解释:输入的二进制串00000000000000000000000010000000 中,共一位为’1’。
解题思路:对位操作的应用,使用n&(n-1)的方法(该方法可以将最后一位1变为0),发现有几个1,就循环几次n&(n-1)得到0。时间复杂度:O(M),M是n中1的个数。
注:下面代码可左右滑动查看
public class Solution {
public int NumberOf1(int n) {
int count = 0;
while (n != 0) {
n &= (n - 1);
count ++;
}
return count;
}
}
```