这里有两个算法,这两个算法都是用按位与进行运算求出二进制数中1的个数。但算法二要精简的好多,如果你们还有比第二种算法还精简的算法请不要吝啬你们手中代码,一起分享一起学习。
算法一
#include<stdio.h>
#include<windows.h>
int main()
{
int n = 0, i = 0, count = 0;
printf("请输入一个十进制数字\n");
scanf("%d", &n);
while (n> 0)
{
if (n&1 == 1)
count++;
n >>= 1;
}
printf("%d\n", count);
system("pause");
return 0;
}
把n的二进制序列按从右往左的顺序依次按位与1(相同的为1,例如1和1.异为0,例如0和1),若判断相同,则给count加1,每次判断完后,把n的二进制序列向右移一个单位,最后输出count为n中1的个数。但是这个算法必须执行完每一位二进制数,无论那一位是1还是0,都得执行才能找出1,很浪费时间。
有没有一种算法是可以二进制数中有几个1,就只执行几次,那么看下面这个算法
算法二
#include<stdio.h>
#include<windows.h>int main()
{
int n = 0, i = 0, count = 0;
printf("请输入一个十进制数字\n");
scanf("%d", &n);
while (n> 0)
n = n&(n - 1);
count++;
}
printf("%d\n", count);
system("pause");
return 0;
}
这个算法巧妙的利用了二进制序列按位与的特征。
n=n&(n-1);每执行一次,二进制数中就少一个1.所以执行几次,就有几个1.
例如: n = 1011 n中有三个1
执行第一次 n-1 = 1010 n=n & (n-1)=1010 n=1010
执行第二次 n-1 = 1001 n=n & (n-1)=1000 n=1000
执行第三次 n-1 = 0111 n=n & (n-1)=0000 n=0000
可以明显看出执行三次后,n为0,跳出循环。