返回参数二进制中 1 的个数

2019-04-14 15:57发布

题目:写一个函数,返回参数二进制中1的个数。
eg: 15——–00000000 00000000 00000000 00001111
思路:
(1)模除
模2 得到最后一位是不是1,如果是1,则count++,
除2去掉最后一位,继续模2,除2 ,直到除2的结果为0。
返回count(1的个数)
(拿到一位,去掉一位,除产生的数为0,则结束)
代码实现: int count_bit_1(int n) { int count=0; while(n) { if(n%2==1) { count++; } n=n/2; } return count; } 看起来似乎很正确,我们测试了几组数据:
这里写图片描述
这里写图片描述
这里写图片描述
15—-4
14—-3
-1—-0
-1中到底有几个1呢?
整型数据要以二进制补码表示。
-1的原码:10000000 ……00000001,-1的补码:11111111 ……11111111。(32位)
所以-1中有32个1。
上述方法只适合计算正整形数据二进制中1的个数。
思路:一个整数有32位,我们把32位每一位判断是不是1,用一个for循环,循环32次。
将参数的二进制序列右移(左移)【 右移>> 左移<<】
右移:将二进制序列向右移一位,左边补符号位。
左移:将二进制序列向左移一位,右边补0。
然后与(&)上1,判断最后一位是不是1.
这里写图片描述
代码实现: int count_bit_1(int n) { int count = 0; int i = 0; for(i=0;i<32;i++) { if((n>>i)&1==1) { count++; } } return count; } 优化:上述代码无论参数有多少个1都循环32次,会有时间上的浪费。
可以做到 “有几个1循环几次”
n=n&(n-1)
每一次计算n的二进制位少了一个1,这个1是这个二进制中最后的一个1,一直与下去,直到为0,与几次,则有几个0.
eg:
4—-0100(只有一个1)
0100&0011=0000(只与一次)
15—-1111(4个1)
1111&1110=1110
1110&1101=1100
1100&1011=1000
1000&0111=0000(与四次)
代码实现: int count_bit_1(int n) { int count=0; while(n) { count++; n=n&(n-1); } return count; } 我在VS2010编译器
如果有误,希望指出