大家好,我是努力变强的铦我们直接进入正题哈。
第一种
我们首先看10和1的二进制序列
假如10按位与1,是否就可以判断最后一位是否为1?显然是可以的。
同理,假如整数n的二进制序列最后一位为0,那么n&1结果就为0,如果最后一位是1,那么n&1结果就为1。
那么只要我们让整数n的二进制序列的每一位都与1按位与就可以求出1的个数了。
int NumberOf1(int n)
{
int count = 0;
int i = 0;
for (i = 0; i < 32; i++)
{
if (((n>>i) & 1) == 1)
{
count++;
}
}
return count;
}
第二种
我们看整数
(其实这种方法和正整数N%10可以求个位数是一样的)
随着n/2的进行,我们发现的二进制序列的1在减少,n最终会为0。如果整数n%2=1的话,就代表n的二进制序列中有一个1了,之后我们统计有多少个1就行了。
但是我们发现当传进去的是负数时,结果就不是我们想要的了,我们只要把传过来的n转化为无符号数m就行
int NumberOf1(int n)
{
unsigned int m = n;
int count = 0;
while (m)
{
if (m % 2 == 1)
{
count++;
}
m /= 2;
}
return count;
}
第三种
我们让整数n&(n-1)后赋给n,然后再让n&(n-1),再赋给n,如此反复
我们是否发现了n&(n-1)与n的二进制序列是否少了一个1?我们统计n&(n-1)的次数就行。
是的,这种方法相较前两种不同,第三种有多少个1就进行几次,显然是优于前两种的。
int NumberOf1(int n)
{
int count = 0;
while (n)
{
n = n & (n - 1);
count++;
}
return count;
}
谢谢大家观看,写得不好还请指出!
---------------------------------------------------------------------------------------------------------------------------------
以上函数需要主函数才可以使用。
#include"stdio.h"
int main()
{
int n = 0;
scanf("%d", &n);
int ret = NumberOf1(n);
printf("%d", ret);
return 0;
}