上一篇文章中,我们提到了位运算这个概念,今天我们试着使用位运算来统计一个数的二进制表示中1的个数。
首先是头文件:
#include<stdio.h>
#include<stdlib.h>
然后先写出主函数:
int main()
{
int num = 0;
printf("请输入一个整数:");
scanf("%d",&num);
printf("%d的二进制序列中有%d个1\n", num, BitCount(num));
system("pause");
return 0;
}
下一步是设计的个叫做BitCount的函数,传入一个整型,返回传入参数二进制表示中1的个数。
想要计算二进制中1的个数,必须用到位运算,上一篇文章中讲到左移(<<)和右移(>>)符号,a>>n表示把一个数的二进制序列最右边的n个位舍弃,再在最左边补上n个符号位,左移则是往相反的方向进行操作,但左移规定补的是零。而这一个函数要用到的令一个位运算是按位与(&),为的是判断二进制序列某个位是否为1。
我们要做的,是把每一个位提取出来,判断其若是1,则让初始值为0的计数器自加。整型的二进制序列有32位,因此要做32次判断,所以做一个for循环,循环内让二进制序列与1(为进制序列为1)按位与,若结果为1,则当前二进制序列最低位为1;若结果为0,则当前二进制序列最低位为0。若当前二进制序列最低位为1,则让初始值为0的计数器自加。每一次循环最后让二进制序列右移一位,32次提取之后便能由计数器统计出二进制序列中1的个数。
写出程序:
int BitCount (int num)
{
int t = 0;
int i = 0;
for(i=0; i<32; i++)
{
if((num&1) == 1)
t++;
num =(num>>1);
}
return t;
}
举个例子,现在有一个整数13,二进制为0000 0000 0000 0000 0000 0000 0000 1011,为了方便说明,在此直接采用1011来代替以上二进制序列。第一次循环中,序列为1011,与1相与,得到1,计数器自加后为1;第二次循环中,序列为0101,与1相与,得到1,计数器自加,为2;第三次循环中,序列为0010,与1相与,得到0,计数器不自加,仍为2;第四次循环中,序列为0001,与1相与,得到1,计数器自加后为3。之后的循环中序列最低位都为0,因此可以忽略,则在13的二进制序列当中有3个1,函数返回3。
看一下输出结果:
此外,这个函数对于负数依然有效,大家可以试着像我刚刚那样分析一下。
而现在的函数写的较为啰嗦,优化后得到:
int BitCount (int num)
{
int t = 0;
for(; num; num>>=1)
{
t +=num&1;
}
return t;
}
这题就完成了!大家有什么问题或者更好的想法,可以在给我下方留言喔!