【C语言学习】————————统计二进制中1的个数


一、与、或、非操作和异或运算

想要统计二进制中1的个数,首先得要知道什么是与、或、非操作以及异或运算。

1.与(&)

进行运算的两个数据,按二进制位进行“与”运算。
规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;
即: 两位同时为“1”,结果才为“1”,否则为0

2.或(|)

进行运算的两个数据,按二进制位进行“或”运算。
运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1;

3.非(~)

1取0,0取1 ~1 = 0, ~0 = 1 ~(10001) = 01110

4.异或(^)

参加运算的两个数据,按二进制位进行“异或”运算。
运算规则:0^0=0; 0^1=1; 1^0=1; 1^1=0

二、算法思路

想要统计二进制中1的个数,首先想到的就是通过循环来实现。

思路一:

我们可以通过将数字对2进行取余操作,通过对2的取余判断是否可以被2所整除。

如果可以被2整除,说明这个数字的二进制位的最低位一定是0,否则的话就是1。如果是1的话,我们就通过+1将最低为变为0。

最后通过判断数字是否等于0,不是就一直进行/2操作使它变成0。

代码如下(示例):

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

但是这种算法有一个缺陷,就是效率太低。

系统一直对2进行取余操作需要耗费过长的时间,效率低而且耗时长。

思路二:

可以直接对int类型的数进行操作。

int类型一共有32位比特位。所以我们可以通过遍历32位比特位统计1的个数

代码如下(示例):

int count_one_bit(unsigned int n)
{
	int count = 0;
	int i = 0;
	for(i=0; i<32; i++)
	{
		if(((n>>i)&1) == 1)
			count++;
	}
	return count;
}

这个算法就通过每一位和1进行&(与)操作,因为&操作是有0则0,所以可以判断该比特位是否为1。这种算法相较于上一种来说效率更高,不需要重复取余操作。但是缺点也比较明显,这个算法无论是判断多大的数字,都需要进行32次的循环操作。

思路三:

可以通过将相邻的两个数字按位进行&操作。

举例:
9999:‭10 0111 0000 1111‬
第一次循环:n=9999   n=n&(n-1)=9999&9998= 9998
第二次循环:n=9998   n=n&(n-1)=9998&9997= 9996
第三次循环:n=9996   n=n&(n-1)=9996&9995= 9992
第四次循环:n=9992   n=n&(n-1)=9992&9991= 9984
第五次循环:n=9984   n=n&(n-1)=9984&9983= 9728
第六次循环:n=9728   n=n&(n-1)=9728&9727= 9216
第七次循环:n=9216   n=n&(n-1)=9216&9215= 8192
第八次循环:n=8192   n=n&(n-1)=8192&8191= 0

代码如下:

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

该种算法相较于第二个算法,循环次数更少,效率更高。此种方法,数据中二进制比特位中有几个1,循环就执行几次,并且中间采用了位运算,处理比起取余操作更加高效。


总结

以上就是今天要讲的内容,通过巧用位运算来实现二进制中1的个数的统计。

如果对你有帮助的话,请支持一下谢谢。

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-_Joker_-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值