zoukankan      html  css  js  c++  java
  • 位1的个数

    这道题出自LeetCode,题目如下:

    编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量)。

    示例1 :

    输入:00000000000000000000000000001011
    输出:3
    解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

    示例2 :

    输入:00000000000000000000000010000000
    输出:1
    解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。

    示例3 :

    输入:11111111111111111111111111111101
    输出:31
    解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。

    这道题的意思很简单,而且有一种在O(1)时间内计算出结果的巧妙解法。要想统计位1的位数,我们可以利用分而治之的思想进行考虑,就是先去统计前16位中1的位数和后16位中1的位数,然后求和即可。类似地,就要先去统计每8位中1的位数,最后划分到最小单位,就是去统计每1位中1的位数然后求和。统计每1位的1的位数很简单,只要看它是否为1即可,为1数量就是1,否则就是0。至于求和,我们注意到,两个1位数之和最多只会是2,而2的二进制表示是10,用两位足够表达,所以直接相加即可。相加之后的结果,就是每2位中保存了这2位中1的数量。以此类推,可以得到每4位中1的数量,每8位中1的数量,一直到最后32位中1的数量,也就是最终答案。通过的代码如下所示:

    class Solution {
    public:
        int hammingWeight(uint32_t n) {
            const uint32_t M1 = 0x55555555;  // 01010101010101010101010101010101
            const uint32_t M2 = 0x33333333;  // 00110011001100110011001100110011
            const uint32_t M4 = 0x0f0f0f0f;  // 00001111000011110000111100001111
            const uint32_t M8 = 0x00ff00ff;  // 00000000111111110000000011111111
            const uint32_t M16 = 0x0000ffff; // 00000000000000001111111111111111
    
            n = ((n >> 1) & M1) + (n & M1);
            n = ((n >> 2) & M2) + (n & M2);
            n = ((n >> 4) & M4) + (n & M4);
            n = ((n >> 8) & M8) + (n & M8);
            n = ((n >> 16) & M16) + (n & M16);
    
            return n;
        }
    };
    
  • 相关阅读:
    一次性能测试的面试问题
    一次APP测试的感悟
    《程序员跳槽全攻略》读书笔记
    如果有人让你推荐编程技术书,请叫他看这个列表
    上班的一天
    马士兵Java视频教程 —— 学习顺序
    月薪3万的技术网站资源收集
    给32岁的自己一些答案
    《Vuser虚拟用户开发》读书笔记
    shell脚本异常:/bin/sh^M:bad interpreter: No such file or directory
  • 原文地址:https://www.cnblogs.com/back-to-the-past/p/15055634.html
Copyright © 2011-2022 走看看