按位异或操作(^)规则:如果两个运算对象的对应位置有且只有一个为1,则计算结果中该位位1,否则为0。
简言之:两个相同的数会变成0,反之是1。
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 1 = 0
1 ^ 0 = 1
使用异或的例子,如Leetcode上有一道题目
Single Number
,题目描述如下:
Given an array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
题目大意就是在给定数组中找出哪个数字是单身狗:(。
解题思想:
(2^1^4^5^2^4^1) => ((2^2)^(1^1)^(4^4)^(5)) => (0^0^0^5) => 5
代码如下:
int singleNumber(vector<int>& nums) {
auto size = nums.size();
int single = 0;
for (int i = 0; i < size; ++i)
single ^= nums[i];
return single;
}
通过按位异或运算,还可以实现两个值的交换,而不必使用临时变量。例如交换两个整数a,b的值,可通过下列语句实现:
a = 10100001, b = 00000110;
a = a ^ b; //a=10100111,记录两者的差异
b = b ^ a; //b=10100001
a = a ^ b; //a=00000110
此外,异或运算可以实现两个整数的相加(其实也是Leetcode上的一道题目 sum of two integers):
int getSum(int a, int b) {
int sum = a ^ b;
int carry = (( a & b) << 1);
return sum + carry;
}
优先级方面,异或运算不高不低:比算数运算符低,但比关系运算符/逻辑运算符/赋值运算符高。
结合律方面,满足左结合律。
一个数的<<和>>运算相当于乘以或除以2的n次幂。例如:3 << 2 = 3 * (2**2) = 12。3 >> 2 = 3 / (2**2) = 0(记住,是整除)。
除此之外,异或运算还有一下用处: