ACM中的位运算技巧

听说位运算挺好玩的,那这节总结一下ACM中可能用到的位运算技巧。

XOR运算极为重要!!(过[LC136](只出现一次的数字 - 力扣(LeetCode)):数组中每个数字都出现两次,只有一个出现一次,找到出现一次的数字)

1. 如果我们对 0 和二进制位做 XOR 运算,得到的仍然是这个二进制位
a⊕0=a
2. 如果我们对相同的二进制位做 XOR 运算,返回的结果是 0
a⊕a=0
3. XOR 满足交换律和结合律
a⊕b⊕a=(a⊕a)⊕b=0⊕b=b

<<一次相当于*2,>>一次相当于/2

使用:

  1. 判断奇偶数(数&1,为1奇数;为0偶数)
  2. 获取二进制为是1还是0(&运算)
  3. 交换两个整数变量的位置(不常用,有编译优化)
  4. 使用异或运算消除重复。
  5. 使用N&(N-1)消掉N的二进制形式的低位0。

 

问题一:判断二进制中1的个数([LC461](汉明距离 - 力扣(LeetCode)), [LC476](数字的补数 - 力扣(LeetCode)):

1.每次二进制位向右移动一位,并&1判断是否结果为1。

2.使用N&(N-1)一次一次消掉低位0,count记录操作次数。count即为二进制中1的个数。

 

问题二:判断一个整数是不是2的整数次方。

问题转化为该整数的二进制形式是否只有一个1,其余全为0。

1 if (((N - 1) & N) == 0)  // 一条语句判断

 

问题三:将整数的二进制形式的奇偶位互换。

1.对i和(i+1)互换,循环中每次步进2位。

2.使用&运算取出二进制的奇数位和偶数位,移动后做XOR。

1 int main()
2 {
3     int i;
4     cin >> i;  // 读取数
5     int ou = i & 0xaaaaaaaa;//与1010 1010 1010 ...做&运算取出偶数位
6     int ji = i & 0x55555555;//与0101 0101 0101 ...做&运算取出奇数位
7     cout << ((ou >> 1) ^ (ji << 1)) << endl;
8 }

 

posted on 2020-04-11 03:12  Black_x  阅读(380)  评论(0编辑  收藏  举报