您的位置:首页 > Web前端

剑指offer-第十题方法总结

2016-05-18 14:16 225 查看
题目:实现一个函数,输入一个整数,请输出这个数的二进制表示中1的个数。例如:输入5,的二进制是101,有两个1则输出2.

这个题目很简单啊!!!
int
count_one(int
n)
[align=left]{[/align]

int
count = 0;

while
(n)
[align=left] {[/align]

if
(n&1)
[align=left] count++;[/align]
[align=left] n=n >> 1;[/align]
[align=left] }[/align]

return
count;
[align=left]}[/align]

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

略微思考一下可以将上面这种方法改进一下,整数有32个bit位,分别将这个数的每一位与1按位与,如果为真,则count++。
int
count_one(int
n)
[align=left]{[/align]

int
i = 0;

int
count = 0;

for
(i = 0; i < 32; i++)
[align=left] {[/align]
count += ((
n
>>i) & 1);
[align=left] }[/align]

return
count;
[align=left]}[/align]

这样确实能够做出来,对于每一个数,都要判断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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: