引:中国某杀毒软件公司2010年3月笔试题
#include <iostream>
using namespace std;
int func(int n)
{
int nCount = 0;
while( n )
{
nCount++;
n = n & (n-1);
}
return nCount;
}
int main(int argc, char *argv[])
{
cout << func( 9999 ) << endl;
return 0;
}
输出结果是多少?
答案是:8
一开始看题目我是没做出来的,因为自己对类似于位操作不是很熟悉,所以即使知道这个是求含1的个数,但是依然没想通。
怎么 n = n & (n-1) 就可以求得1的个数呢。
后来分析下,有了些许的明白。
解释可以如下:
比如对于某二进制数 n=1xxx...100
那么n-1=1xxx...011
那么n & (n-1) = 1xx...000
这样的话,每进行一次n&(n-1)运算,那么n的末尾1都会消除掉,这样的话每一次都会消掉一个1,到最后n就为0了,如此就可以知道n含有多少个1了。
附:
某面试题要求用一个表达式来判断一个整数是否为2的n次方,实质上,我们只要判断该整数含1的个数是否为0即可。所以表达式可表示为:
!(n & (n-1) )
如果为真那么就说明是。
#include <stdio.h>
int GetOneCountsByDiv( int x )/*除法*/
{
int n=0;
while( x )
{
if( x%2 ) n++;
x /=2 ;
}
return n;
}
int GetOneCountsByMoveR( int x )/*右移位操作*/
{
int n=0;
while( x )
{
if( x&1 ) n++;
x = x>>1;
}
return n;
}
int GetOneCountsByAnd( int x )/*n和(n-1)与操作*/
{
int n=0;
while( x )
{
x &= (x-1);
n++;
}
return n;
}
int main(int argc, char *argv[])
{
printf( "%d", GetOneCountsByAnd(9) );
return 0;
}