街角_祝福

导航

测试整数(二进制)含1个数

引:中国某杀毒软件公司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;
}


posted on 2012-06-19 17:52  街角_祝福  阅读(188)  评论(0编辑  收藏  举报