0
点赞
收藏
分享

微信扫一扫

求一个整数在内存中存储的二进制序列中1的个数的三种思路

千白莫 2022-03-11 阅读 80

先将代码敲出来

方法一:

#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就停止循环。

举报

相关推荐

0 条评论