C++计算int中1的个数
在 C++ 中,计算一个 int
整数的二进制表示中
1
的个数(也称为 Population Count 或
Hamming Weight)有多种方法。以下是几种常见的方法:
方法 1:逐位检查(循环移位法)
int countOnes(int num) |
说明:
- 遍历整数的每一位(共 32 位)。
- 使用
1 << i
生成掩码,检查该位是否为1
。 - 优点:简单直观,适用于所有整数。
- 缺点:循环次数固定为 32 次,效率较低。
方法 2:Brian Kernighan 算法(优化版)
int countOnes(int num) |
说明:
num &= (num - 1)
会清除num
最低位的1
。- 优点:循环次数等于
1
的个数,效率更高。 - 缺点:对于
num = 0
的情况也能正确处理。
方法 3:使用
std::bitset
(C++标准库)
|
说明:
std::bitset
提供了count()
方法直接统计1
的个数。- 优点:代码简洁,可读性强。
- 缺点:需要包含头文件
<bitset>
,可能不如位操作高效。
方法 4:编译器内置函数(高效实现)
int countOnes(int num) |
说明:
__builtin_popcount
是 GCC 和 Clang 提供的内置函数,直接调用硬件指令(如POPCNT
)。- 优点:效率最高(单条 CPU 指令)。
- 缺点:非标准,仅适用于
GCC/Clang,MSVC 需用
__popcnt()
。
方法 5:查表法(适用于频繁调用)
int countOnes(int num) |
说明:
- 预计算 8 位整数的
1
的个数,然后分段查表。 - 优点:无循环,适合高频调用场景。
- 缺点:需要额外的静态表,占用内存。
性能对比
方法 | 时间复杂度 | 适用场景 |
---|---|---|
逐位检查 | O(32) | 通用,简单 |
Brian Kernighan | O(1的个数) | 高效,推荐 |
std::bitset |
O(1) | 代码简洁 |
内置函数 | O(1) | 极致性能(GCC/Clang) |
查表法 | O(1) | 高频调用 |
示例代码(Brian Kernighan 算法)
|
总结
- 推荐方法:Brian Kernighan 算法(平衡性能和可读性)。
- 极致性能:使用
__builtin_popcount
(GCC/Clang)或__popcnt()
(MSVC)。 - 代码简洁:
std::bitset
。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 qyhome!