请实现一个函数,输入一个整数,输出该数二进制示意中 1 的个数。例如,把 9 示意成二进制是 1001,有 2 位是 1。因此,若是输入 9,则该函数输出 2。

测试用例1:

测试用例2:

测试用例3:

首先来剖析问题,要统计二进制中1的个数,那么我们首先想到的是 要将此数的每个比特位都要遍历一遍,然后判断为1count++,最后返回count。就写出如下代码

,

以太坊开奖

www.326681.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。

,
int hammingWeight(uint32_t n) {
        int count = 0;
        while(n)
        {
            if(n&1)
                count++;

            //此处移位时,若是n为负数可能会导致死循环
            n >>= 1;
        }
        return count;
    }

上面的代码在统计无符号数时,效果是准确的,然则,在算负数时,可能会导致死循环。
此处我们接纳的 位运算 来取代 除法运算,由于计算机中除法的效率要比比移位运算要低得多。我们在现实编程中要尽量地用移位运算符取代乘除法。
再者我们来讨论一下测试用例为负数。右移运算符的特点是,右移n位的时刻,最右边的n位将被抛弃。在右移处置最左边位的情形对照复杂。若是数字是一个无符号值,则用0填补最左边的n位;若是数字为有符号数,则用数字的符号位填补最左边的n位。也就是说,若是数字原先是正数,则右移之后在最左边补n个0;若是数字原先是负数,则右移之后在最左边补n个1。 以是负数在举行移位时,最终由于最高位一直补1导致最终效果陷入死循环。故设计出上述代码是由问题的,我们可以对其举行调整。

  • 准确树模1:
int hammingWeight(uint32_t n) {
        int count = 0;
        unsigned int flag = 1;
        while(flag)
        {
            if(n&flag)
                count++;

            flag = flag << 1;
        }
        return count;
    }

为了制止死循环,此处我们不右移输入的数字n,而是把n和1 按位与 ,判断i的最低位是不是为1,接着把i左移1位,再和n做按位与运算。这样频频右移就能计算出n中二进制位1的个数。这种解法惟一的不足之处是无论n中二进制位有多少个1,都要举行32次循环。那么还能不能在优化一下呢,谜底是一定可以,来看一下最终对照完善的解答:
完善解答:

int hammingWeight(uint32_t n) {
        int count = 0;
        while(n)
        {
            ++count;
            n = (n-1)&n;
        }
        return count;
    }

此处将位运算的灵活性体现到了机制,可以看出代码设计的异常巧妙精简。其精髓就在于此句 n = (n-1)&n 。人人可以自己体会一下此处的妙笔。