突然想把自己每天学到的知识记录下来,于是乎产生了这篇博客。
这一篇博客的主要目的是通过写一个函数使其能够返回参数二进制中1的个数,方法一共有三种。
第一种方法十分简单。我们举一个十进制数字的例子,更易理解。
我们要想统计十进制数字中出现的1的个数,只需要对这个数字进行“/10”与“%10”运算。比如对数字119,119 % 10 = 9,我们得到了这个数字的个位数,观察其个位数与1是否相等,相等的话1的个数就加一;然后进行整除运算119 / 10 = 11,由此我们丢弃了这个数字的个位数,得到了这个数字的前两位数。依次类推,我们再对11进行这两步运算,可以得到其个位数与除去个位数的数字。我们只要判断得到的个位数中1的个数即可。
对二进制亦是如此,只不过除数从10变为了2。代码如下。
int count_bit_one(unsigned int n) //unsigned是考虑到输入的数字可能为负数 { int count = 0; while (n) { if (n % 2 == 1) //即该二进制最后一位为1 count++; n = n / 2; //得到除去最后一位的二进制序列 } return count; } int main() { int a = 0; scanf("%d", &a); int count = count_bit_one(a); //定义一个函数能够数‘1’ printf("count = %d\n", count); return 0; }
第二种方法相较于第一种更为简便,我们通过‘>>’操作符与‘&’操作符来实现该函数。
‘&’操作符只有两个都为1才会返回1,比如说,10101&00001=00001,我们可以利用这一特点来判断该二进制序列中最后一位是否为1,判断完最后一位后,我们希望能够判断倒数第二位的情况,我们可以借鉴第一钟方法的思想,通过‘>>’操作符——左边补0,右边丢弃——来实现。通过右移操作符,我们丢弃了该二进制序列的最后一位,并且在左边补0(这使得最终的结果不会受到影响),因此我们可以判断原二进制序列倒数第二位的情况。以此类推,我们可以计算出整个二进制序列中1的个数。代码如下。
int count_bit_one(int n) { int count = 0; int i = 0; for (i = 0; i < 32; i++) //占32个bit位 { if (((n >> i) & 1) == 1) { count++; } } return count; } int main() { int a = 0; scanf("%d", &a); int count = count_bit_one(a); printf("count: %d", count); return 0; }
第三种方法十分巧妙。我们随便书写一个二进制序列:1101,1101&1100,得到1100,我们发现原二进制中最右边的1消失了;再将1100&1011,得到1000,发现二进制序列中1100最右边的1也消失了。由此我们可以看到,当进行运算“n=n&(n-1)”时,会使得n的二进制序列的最右边的1消失,我们可以利用这种特性来计算二级制序列中1的个数。代码如下。
int count_bit_one(int n) { int count = 0; while (n) { n = n & (n - 1); count++; } return count; } int main() { int a = 0; scanf("%d", &a); int count = count_bit_one(a); printf("count:%d", count); return 0; }
这是俺的第一篇博客,格式、条理啥的可能都很混乱,但是,我会继续努力的!对于文中的错误,欢迎大家指出,先提前谢谢大家啦!让我们共同进步!