统计二进制中的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的个数。
客官,都看到这儿了,求一个三连支持呀~~