出处——《剑指offer》
题目:实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2。
1.假设要检测9的二进制中1的个数(1001),将其与1(0001)求‘与’来判断其最右边的一位是否为1,可以通过对9(1001)进行循环右移并与1(0001)求‘与’来得到总的1的个数,也可以通过对1(0001)循环左移并与9(1001)求‘与’来得到1的个数。但考虑到当对负数进行右移时,二进制最左边会使用1进行填充,而不是使用0,会使得循环判断条件始终为真,陷入死循环(使用while( n )时),因此采用对1(0001)进行循环左移的方法。
int NumberOf1( int n )
{
int count = 0;
unsigned int flag = 1;
while( flag ) /*循环次数等于整数二进制的位数*/
{
if( n & flag )
count++;
flag = flag << 1;
}
return count;
}
2.进阶解法
把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。
例:
第一次循环
12(1100) - 1 = 1011
1011 & 1100 = 1000
第二次循环
1000 - 1 = 0111
0111 & 1000 = 0000
循环结束,count = 2,即1的个数为2个
int NumberOf1( int n )
{
int count = 0;
while( n )
{
++count;
n = ( n - 1 ) & n;
}
return count;
}