目录
一、题目要求
求一个整数存储在内存中的二进制中的1的个数。
通过题目我们可知,一个整数在内存中的二进制数位是这个整数的补码,因此求的是这个整数的补码中的1的个数。
二、解题思路
(一)方法一
1 ) .分析
换位思考,若寻求一个整数中1的个数,我们恐怕一开始想的便是将这个整数的各个位数分离,随后再用循环的方式,进行以此判断,并以此统计。
而将一个整数各个位数分离的方法,我们可以采用先 %10 后 /10的方法,前者取出最低位的数字,后者去除最低位的数次,并加以循环,我们便可以得到一个整数的所有位数。
列如:
123 %10 = 3
123 / 10 = 12
12 % 10 = 2
12 / 10 = 1
1 % 10 = 1
1 / 10 = 0
当最后的答案得出0时,循环便已经结束了。
所以,我们可以采用这种方法,解决二进制数的各个位数的分离
例如:
1111 - 15的二进制
15 % 2 = 1
15 / 2 = 7
111 - 7的二进制
7 % 2 = 1
7 / 2 = 3
11 - 3的二进制
………………………………
以此类推
但是此方法在面对负数时会出现问题,于是,又产生了一个新的方法,使用>>和&.
&具有判断是否为1的功能,当配合>>使用,则可以判断每一位的数位是否为1
& 的功能详情在http://t.csdn.cn/mqp1G
于是有了以下的代码演示
2 ).代码演示
int main()
{
int a = 0:
scanf("%d"&a);
int i = 0;
int count = 0;
for (i = 0;i < 32; i++)
{
if ((a >> i) & 1) == 1)//进行移位判断,利用了&的性质
{
count++;//等于1的进行统计,不等于1的直接进入循环
}
}
printf("%d\n",count);
return 0;
}
(二)、方法二
1 ) .分析
例如:
int n = 13;
1101 - n的补码
1100 - n-1的补码
1100 - n & (n-1)的结果 ,令这个 n & (n-1)成为新的n
1100 - n的补码
1011 - n-1的补码
1000 - n&(n-1)的结果,令这个 n & (n-1)成为新的n
1000 - n的补码
…………………………
通过以上,我们得知新的n和老的n相比,二进制数位上的1在逐渐的减少,并且是从右往左的方向以此减少,所以,我们可以得到一个规律,n = n & (n-1) 在不断的减少二进制位数上的1.
所以,我们产生了以下代码。
2 ). 代码演示
int main()
{ int n = 0:
scanf("%d",&n);
int count = 0;
while (n)
{
n =n & (n - 1);
count++;
}
printf("%d\n",count);
return 0;
}