您的位置:首页 > 其它

位运算(一):二进制中1的个数

2016-05-29 23:22 316 查看
一、题目:求二进制中1的个数

请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。

例如:10 二进制表示为:1010 ,该函数输出二

二、最初思路:

先检查二进制位最右边一位是否为1,将二进制位右移一位,这时最右边一位

变为原来的倒数第二位,再右移一位,依次循环运算,直到此数变为0。

怎样检查二进制位最右边一位是否为1呢?用这个数&1,若结果为0,则是0,否则为1。

三、改进:

1.输入的数为负数,最高位为1,右移时最高位会填充1,用上述方法则会死循环。

思路应修改为:先&1判断最右边一位是否为1,然后将1左移一位再&判断右边第二位

是否为1,与运算的结果为0,则该位不是1,否则都为1。直到1左移为0结束循环.

2.上述思路32位整数需要移动32次,改进为整数中有多少个1就循环多少次。

思路应修改为:将一个整数减去1然后与这个整数做与运算,结果恰好将最右边的1变为0。

例:最低位为1:(1001)&(1000)= 1000

最低位为0:(1010)&(1001)= 1000

四、代码实现(编译器:VS2010 语言: C语言)

#include <stdio.h>
#include <stdlib.h>

int NumberOfOne(int n)
{
int count = 0;
/*方法1:最初思路 未解决负数问题
while(n)
{
if((n&1) == 1)
{
count++;
}
n>>=1;
}*/
/*方法2:改进1  32位整数要循环32次
unsigned int flag = 1;
while(flag)
{
if(flag & n)
count++;

flag <<= 1;
}*/

//方法3:终极方法 优化了方法2,有多少1就循环多少次
while(n)
{

n &= (n-1);
count++;

}

return count;
}
int main()
{
int num = -10;

//-10在内存中的存储,求-10的补码

//10000000 00000000 00000000 00001010  ->10
//11111111 11111111 11111111 11110101  ->取反
//11111111 11111111 11111111 11110110  -〉+1
int ret = NumberOfOne(num);
printf("%d\n", ret);
system("pause");
return 0;
}


参考书籍《剑指offer》

谢谢阅读,如有错误,欢迎指出,在此感谢!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: