二进制中1的个数
题目:
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如,把9表示成二进制是1001,有2位是1.因此,如果输入9,那么函数输出2
有这样一个段子:
世上有10种人,一种人知道二进制,而另一种人不知道二进制
二进制运算是十分重要的。
高效而便捷
如果我们按部就班,只看最后一位,但判断之后进行移位,直到最后数完。可以写出以下代码:
int NumberOfl(int n)
{
int count=0;
while(n)
{
if(n & 1)
count++;
n=n>>1;
}
return count;
}
看起来似乎没啥问题,但是如果是负数的话,比如0x80000000,当右移一位的时候,不是变成0x40000000,而是0xC0000000,那么到最后就会变成0xFFFFFFFF。显然这样会陷入死循环。
那么我们可以引进一个flag值,这样可以避免死循环。先将flag置为1,这次每次循环讲flag左移,与n作与,这样就能将1的个数统计出来了
代码如下:
int NumberOfl(int n)
{
int count=0;
unsigned int flag=1;
while(n)
{
if(n & flag)
count++;
flag=flag<<1;
}
return count;
}
这样在32次(或者63次)循环之后,就可以将1的个数数出来了。
但是毕竟还是循环了32次,有没有什么办法,减少循环次数呢?
其实在按位运算时,有许多的技巧,比如我们现在可以用到一条:
对于一个n,如果要去掉n的二进制最后一个1,可以这样获得(n-1)&n。
那么就可以得到下面的代码:
int NumberOfl(int n)
{
int count=0;
while(n)
{
++count;
n=(n-1)&n;
}
return count;
}
这样有多少个1就循环几次。大大减少了循环次数。
————————————————————————————————————————————
参考书籍《剑指offer》