剑指offer-第十题方法总结

题目:实现一个函数,输入一个整数,请输出这个数的二进制表示中1的个数。例如:输入5,的二进制是101,有两个1则输出2.

这个题目很简单啊!!!
int count_one( int n)
{
                 int count = 0;
                 while (n)
                {
                                 if (n&1)
                                count++;
                                n=n >> 1;
                }
                 return count;
}


     写出上面的代码是有问题的,如果输入负数,则进行的是算术移位,就会陷入死循环。


     略微思考一下可以将上面这种方法改进一下,整数有32个bit位,分别将这个数的每一位与1按位与,如果为真,则count++。
int count_one( int n )
{
                 int i = 0;
                 int count = 0;
                 for (i = 0; i < 32; i++)
                {
                                count += (( n >>i) & 1);
                }
                 return count;
}

    这样确实能够做出来,对于每一个数,都要判断32次,很麻烦。


      那么有没有一种方法能够使得一个数二进制中有多少个1, 就循环多少次呢???
       答案是有的。

先看看下面这些式子找一找规律:
 1、
10    &    9      =8
1010       1001 =1000

2、
 8     &  7        =0
1000      0111 =0000

3、
 5    &   4    =4
101      100 =100

4、
 4     & 3      =0
100      011  =000

可以发现,n&(n-1)的结果与n相比,其二进制中1的个数少了一个。

根据这样的规律我们可以很容易的实现这道题目的最优解。

int count_one(int n)
{
	int count = 0;
	while (n)
	{
		n = n&(n - 1);
		count++;
	}
	return count;
}


你可能感兴趣的:(剑指offer-第十题方法总结)