统计二进制中1的个数(三种方法)

统计二进制中的1的个数


前言

在关于解决统计一个十进制数转化为二进制后1的个数,有比较精炼的三种方法,三种方法中有较为笼统的 unsigned int 法,但是在一些做题网站上不适用,例如:牛客网调用的函数在C clang编译器中只能用 int 类型的,但自己在下面做题中却可以用 unsigned int 类型的,所以,跟上此篇脚步,来熟悉并掌握这三种解题思路和方法吧!


一、函数调用unsigned int类型

闲话不多聊,先上代码:

#include<stdio.h>
int Print(unsigned int n) {    //unsigned 是将有符号的数字转化为二进制的补码存储到内存当中
	int cnt = 0;
	while (n > 0) {
		if (n % 2 == 1) {
			cnt += 1;
		}
		n /= 2;
	}
	return cnt;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int cnt = Print(n);
	printf("%d", cnt);
	return 0;
}

所以到这里有人问了,unsigned 类型是什么?unsigned是将有符号的数字转化为二进制的补码存储到内存当中,当然,牛客网上所给的函数只能调用int类型的函数, 接下来是两种int类型的代码。

二、右移加按位与

#include<stdio.h>
int ERJINZHI(int n) {
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++) {
		if (((n >> i) & 1) == 1) {    //  1111111111111110  将这个数的二进制的每一位往右移动与1
			count++;                  //& 0000000000000001  进行按位与的运算,若出来的是1则count
		}                             //  0000000000000000  加1.
	}
	return count;
}
int main() {
	int n = 0;
	scanf("%d", &n);
	int ret = ERJINZHI(n);
	printf("%d", ret);
	return 0;
}

解题思路:制作一个循环,32位,将n向右移i位,再与1进行按位与的操作,如果一个位有0,则该位为0,每当出现一个1,则计数器加一,最后返回为计数器的值。

三、相邻的按位与

#include<stdio.h>
int ERJINZHI(int n) {
	int count = 0;
	while (n) {                        //
		n = n & (n - 1);               //  1011   n (十进制的11)
		count++;                       //& 1010  n-1(十进制的10)
	}                                  //  1010   n (十进制的10)#1
	return count;                      //& 1001  n-1(十进制的9)
}                                      //  1001   n (十进制的9) #2
int main()                             //& 1000  n-1(十进制的8)
{                                      //  1000   n (十进制的8) #3
	int n = 0;                         //& 0111  n-1(十进制的7) 
	scanf("%d", &n);                   //  0000   n (十进制的0) #4
	int ret = ERJINZHI(n);             //  
	printf("%d", ret);
	return 0;
}

这个计算比较巧妙,将该位与下一位进行按位与的操作,由四位数字可以推出,每进行一次按位与,则计数器加一,直到数字都为0的时候,此时计数器的值就是要输出的值,即:二进制中1的个数。

总结

求二进制中1的个数,可以用三种方法,但这三种方法也各有优缺点,这题的解题思路是由数学思维进行运算,尤其用到按位与的操作,大家伙想不到很正常,但要勇敢尝试,一点点分析,求出1的个数。
客官,都看到这儿了,求一个三连支持呀~~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

jjrenhai

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

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

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

打赏作者

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

抵扣说明:

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

余额充值