位运算

1.遍历二进制位 + 记录奇偶位

题目:奇偶位数

  • 遍历一个数的二进制位,记录奇偶位1的个数:
class Solution {
public:
	vector<int> evenOddBit(int n) {
		vector<int>ans(2);
		for (int i = 0; n; i ^= 1, n >>= 1)
			ans[i] += n & 1;

		return ans;
	}
};
  • 或者是位掩码,用16进制的0x55555,即二进制的010101...,直接与运算记录对应位置1的个数:
 class Solution {
 public:
     vector<int> evenOddBit(int n) {
         const int MASK = 0x5555;
         return {__builtin_popcount(n & MASK), __builtin_popcount(n & (MASK >> 1))};
     }
 };

2.对每一个二进制位取反

题目:数字的补数

简化题目:对一个数num的每一个二进制位取反,去掉前导0后输出对应的十进制数

思路:先求出num最高位的1,假如位置在s,然后设置一个最高位s为1,其余位为0的数字n,即n = 1 << s,然后 n - 1 就是前 s - 1 位都为1的数字,将其与num取反后的数按位与后,就可以实现对num每一个二进制位取反的效果(num的s位取反后肯定为0,所以不用管它)。

忘记取反运算符~的话看这里 取反运算符

class Solution {
public:
	int findComplement(int num) {
		int s = -1;
		for (int i = 31; i >= 0; --i) {
			if ((num >> i) & 1 != 0) {
				s = i;
				break;
			}
		}

		int n = 1 << s;

		return ~num & (n - 1);
	}
};

简单一点的取反可以看 4.判断一个数的二进制位是否有相邻的0

3.计算二进制位1的个数

题目:位1的个数

一个比较重要的模版,需要记下来

class Solution {
public:
	int hammingWeight(int n) {
		int ans = 0;
		
		while (n) {
			ans++;
			n &= (n - 1);
		}

		return ans;
	}
};

4.判断一个数的二进制位是否有相邻的0

求一个数num的二进制位中是否有相邻的0,可以对num取反后求是否有相邻的1。

假如num二进制位有n位,先求一个n位全为1的掩码:mask = (1 << n) - 1 ,num取反后的数x为 x = num ^ mask ,如果 (x & (x >> 1))的结果为0,则表示x的二进制位中没有相邻的1,即num中没有相邻的0。

可以做这道题了:生成不含相邻0的二进制字符串

posted @   Amroning  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示