位运算总结
~ 补码
正数的补码:按位取反,末位加1
& 与
只有当相应位上的数都是1时,该位才取1,否则该为为0
| 或
只要相应位上存在1,那么该位就取1,均不为1,即为0
^ 异或
只有当相应位上的数字不相同时,该为才取1,若相同,即为0。
//不使用额外O(1)空间来交换a,b的值
a = a ^ b;
b = b ^ a;
a = a ^ b;
<< 左移
用来将一个数各二进制位全部向左移动若干位
左移n位,即表示乘以以2^n
>> 右移
用来将一个数各二进制位全部向右移动若干位
右移n位,即表示除以2^n
应用技巧
1.1 将0变成1,1变成0,采用异或运算效率更高
a = 1 - a; //法一
a ^= 1; //法二
1.2 任意数异或自身都为0,用来消除出现偶数次的数
leetcode 136 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
# @python2.7
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
ans = 0
for i in nums:
ans ^= i
return ans
1.3 不通过 ‘+’ ‘-’ 实现加减运算
- 具体参见 leetcode 371. 两整数之和
class Solution {
public:
int getSum(int a, int b) {
if(a&b) return getSum(((a&b)<<1),a^b);
else return a|b;
}
};
1.4 计算二进制中有多少个1
- 思路:n & (n-1)可以把最右边的一个1变成0
- 重复以上步骤,知道n变为0;其中重复的次数就是1的个数
1.5 计算一个char的8bit上所以的二进制,即ascci值
void get8Bit(char a) {
for (int i=7; i>-1; i--) {
// 1<<i 表示2^i,例如1<<3表示8: 1000
// a & (1<<i) 的作用在于: 验证该位是否为1
// 最后 != 0 目的在于,如果该位1,那么输出1,该位0则输出0
cout << int((a & (1<<i)) != 0);
}
}