先将代码敲出来
方法一:
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int i = 0;
int count = 0;
for (i = 0; i <= 31; i++)
{
if (1 & (n >> i))
count++;
}
printf("%d", count);
return 0;
}
也是最常规的一种方法,将这个整数的二进制序列按位与上1,就能判断出该整数二进制序列中最后一位是否是1,将整数的二进制循环向右移,就能判断该序列的中总共有多少个1.
方法二:
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int count = 0;
while (n)
{
if (n % 2 == 1)
count++;
n /= 2;
}
printf("%d", count);
return 0;
}
为什么要将这个整数对2取模,然后又整除呢?我们都知道,整数在十进制的表示方法中,例如139,如果我们想要获得个位上的数字9,我们可以令 139%10,就得到最后一位的9,再整数10,将最后一位9给去掉,得到13,再循环上述操作。 同理,在整数用二进制来表示的时候,如果对2取模,就得到最后一位数字,再整除2,就去掉最后一位数字,再对2取模,如果等于1,就让计数器++。
但是,当运行的时候,我们发现出了bug。因为当我输入-1的时候,结果却为0。我们都知道,-1在内存中存储的32bit位上全部都是1,它的二进制序列中怎么会没有1呢??这是因为 -1 本来就是一个有符号整形,在计算的过程中只能执行一次循环。那这个代码不就出现bug了???
我们不要忘了如果仅仅只是想计算一个 -1 这个补码中1的个数,它的补码也可以用来表示一个非常大的无符号整形。所以,在使-1这个补码的二进制序列不变的情况下,可以转换成无符号整形,这样就能在循环中计算了。
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
unsigned int m = n;
int count = 0;
while (m)
{
if (m % 2 == 1)
count++;
m /= 2;
}
printf("%d", count);
return 0;
}
方法三:
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int count = 0;
while (n)
{
n = n & (n - 1);
count++;
}
printf("%d", count);
return 0;
}
这个方法非常巧妙啊兄弟们!!
我们可以自己尝试一下,每当将n&(n-1)的值赋给n,都会将原本n的二进制中的1减少一位,此时计数器就++,一直到n的二进制序列中没有1,就为0,为0就停止循环。