计算一个十进制数的二进制表示有多少位1
一、看个例子
5的二进制为101
含有2个1
15的二进制为1111
含有4个1
二、实现原理
通过位运算中的&
运算将数字二进制中的1变成0,即每进行一次操作二进制表示中的1就减少一位,当所有的1都变为0的时候,数字就变成了0。
怎样用&
将二进制某一位上面的1变为0
因为
当与运算&
左右两边值都为1时,结果为1
当与运算&
左右两边有一边值为0时,结果为0
所以
- 1.如果数字二进制表示的某一位为1,将这一位和0进行
&
运算后得到的结果中,这一位就变为0。 - 2.我们是从低位开始,将1变为0,也就是先将最右边的1变为0。
- 3。a-1的妙用,根据上一句话,我们可以知道当前要消除的1为最右边的1,所以可以将其右边全部看成是0,a-1会将右边的0全部变成1(0减去1向前借位),而本身由于借位变成0,这样就达成了1的目标。
举个例子n二进制为
1101
,等价于110100
,n-1的二进制为110011,则110100&110011结果的二进制为110000
假定数字为a,具体实现
1.将数字a和a-1进行与操作,得到的结果为消除掉最右边1后的十进制数
2.统计1的个数的变量的值加1
3.判断a是否为0,若为0则统计结束,否则继续进行1、2步操作
三、C语言代码实现
#include<stdio.h>
int main()
{
int i, num, count;
scanf("%d", &n);
count = 0;
while(n > 0) {//统计
n = n & n-1;//将当前最右边的1变为0
count++;
}
printf("%d\n", count);
return 0;
}
四、时间复杂度分析
时间复杂度主要耗在while循环里面,而循环执行的次数取决于该数二进制表示有多少个1,所以时间复杂度为线性。
参考:
http://www.cnblogs.com/grenet/archive/2011/06/10/2077228.html