统计二进制数中1的个数
内置位计数功能
C++内置了计算函数。
代码
1 | |
复杂度分析
- 时间复杂度:。实现方法各异,可以近似认为其时间复杂度为 。
- 空间复杂度:。
移位实现位计数
记 ,我们可以不断地检查 的最低位,如果最低位为 ,那么令计数器加一,然后我们令 整体右移一位,这样 的最低位将被舍去,原本的次低位就变成了新的最低位。我们重复这个过程直到 为止。这样计数器中就累计了 的二进制表示中 的数量。
代码
1 | |
复杂度分析
- 时间复杂度:
- 空间复杂度:
Brian Kernighan 算法
在移位实现位计数算法中,对于 的情况,我们需要循环右移 次才能得到答案。而实际上如果我们可以跳过两个 之间的 ,直接对 进行计数,那么就只需要循环 次即可。
我们可以使用 Brian Kernighan 算法进行优化,具体地,该算法可以被描述为这样一个结论:记 表示 和 进行与运算所得的结果,即 ,那么 恰为 删去其二进制表示中最右侧的 的结果。
基于该算法,只需要不断让 ,直到 即可。这样每循环一次, 都会删去其二进制表示中最右侧的 ,最终循环的次数即为 的二进制表示中 的数量。
代码
1 | |
复杂度分析
- 时间复杂度:
- 空间复杂度:。
参考
- Brian W. Kernighan and Dennis M. Ritchie, The C Programming Language (Second Edition)
- Peter Wegner, CACM3, 1960