输入一个数字,求二进制中1的个数

本文介绍三种高效算法来计算一个整数中二进制表示的1的个数,包括位运算、模除操作及巧妙的迭代减1与按位与运算。

在讲方法前,我们先了解一下前置知识

我们要知道1个整型在内存中的二进制是32个bit位

然后会采用&这个位运算符,即对应二进制位,有0则为0,同时为1才为1

方法一:

根据我们的前置知识,

00000000000000000000000000000101 —— 5 的二进制

00000000000000000000000000000001 —— 1 的二进制

00000000000000000000000000000001 —— 5 &1 的二进制

00000000000000000000000000000010 —— 5 >> 1 ( 5 右移一个bit位)

00000000000000000000000000000001 —— 1 的二进制

00000000000000000000000000000000 —— 5 &1 的二进制

以此类推

int found_1(int n)
{
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)// 因为 i 是从 0 开始的,第一次 n >> i 相当于没有移
	{
		if (((n >> i) & 1) == 1)
		{
			count++;
		}
	}
	return count;
}




int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = found_1(n);
	printf("%d", ret);
	return 0;
}

方法二:

假如是一个十进制数,我们想要得到每一位,我们可以%10/10

1234 % 10 = 4

1234 / 10 = 123

123 % 10 = 3

123 / 10 = 12

二进制则同理捏

假如 10 这个数,它的二进制数是 00000000000000000000000000001010

10 % 2 = 0 —— 相当于把 10 的二进制的最低位也就是最右边的 0 拿到了

10 / 2 = 5 —— 5 的二进制是 00000000000000000000000000000101 相当于去掉了 10 的二进制最低位也就是最右边 0 

5 % 2 = 1 —— 相当于把 5 的二进制的最低位也就是最右边的 1 拿到了

5 / 2 = 2 —— 2 的二进制是 00000000000000000000000000000010 相当于去掉了 5 的二进制最低位也就是最右边 1

2 % 2 = 0 ——  相当于把 2 的二进制的最低位也就是最右边的 0 拿到了

2 / 2 = 1 —— 1 的二进制是 00000000000000000000000000000001 相当于去掉了 2 的二进制最低位也就是最右边 0

所以我们直接上代码

int found_1(int n)
{
	int count = 0;
	while (n)
	{
		if (n % 2 == 1)
			count++;
		n = n / 2;

	}
	return count;
}




int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = found_1(n);
	printf("%d", ret);
	return 0;
}

方法三:

这个方法比较巧妙,

n = n & ( n-1 ) ,假如输入 n = 13 ,13 的二进制 1101

1101 —— n

1100 —— n-1

1100 —— n & n-1 再赋给 n、

1011 —— n-1

1000 —— n & n-1 再赋给 n

0111 —— n-1

0000 —— n & n-1 再赋给 n

执行几次就有几个1,直至n=0为止

int found_1(int n)
{
	int count = 0;
	while (n)
	{
		n = n & (n - 1);
		count++;
	}
	return count;
}




int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = found_1(n);
	printf("%d", ret);
	return 0;
}


 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值