目录
正文前的碎碎念
开个新系列,不定期的更新一些我在刷题中遇到的一些有趣的题目或者一些题目有趣的解法。目前咱只学了C语言,所以题解基本以C语言为主。
同样一道题,你有种解法,我有种解法,一交流,咱们都有两种解法了。(第一题)
题目
输入一个整数 n ,输出该数32位二进制表示中1的个数。其中负数用补码表示。
即范围为:−2147483648<=n<=2147483647
解法一:
思想:利用移位操作符和按位与操作符,将输入数字和数字 ‘1’ 进行操作,从而获得该数32位二进制表示中1的个数。
这里以输入数字是 ‘5’为例。
5 :00000000 00000000 00000000 00000101
1 :00000000 00000000 00000000 00000001
1&15 :00000000 00000000 00000000 00000001当最后一位是‘1’时和1按位与得到结果是一。
将输入数字向右移一位得到↓
5>>1 :00000000 00000000 00000000 00000010将移位后得到的数再和1 按位与
:00000000 00000000 00000000 00000000
最后一位是‘0’时和1按位与得到结果是零。
重复以上操作,将32位数字全部判断。
不足:每次计算都要进行32次循环,存在一定的浪费。
代码:
#include<stdio.h>
int NomberOf1(int n)
{
int count = 0;//用来计数,当按位与后的值为‘1’时就加1;
int i = 0;
for (i = 0; i < 32; ++i)
{
if (((n >> i) & 1) == 1)
{
count++;
}
}
return count;
}
int main()
{
int n = 0;//接收输入的数字
scanf("%d", &n);
int ret = NomberOf1(n);//用ret接收输入数字中含‘1’的个数。
printf("%d\n", ret);
return 0;
}
解法二:
思想:n = n&(n-1),n每次和n-1 按位与的时候,会将n的最靠右的一个'1'变为'0'。
这以输入数字是’5‘为例
n :00000000 00000000 00000000 00000101
n-1 :00000000 00000000 00000000 00000100n&(n-1) :00000000 00000000 00000000 00000100
n = n&(n-1)
n :00000000 00000000 00000000 00000100
n-1 :00000000 00000000 00000000 00000011
n&(n-1) :00000000 00000000 00000000 00000000
n = n&(n-1)
n :00000000 00000000 00000000 00000000
n等于零,其中没有1,结束判断。
不足:我想不出来O.o
代码:
int NomberOf1(int n)
{
int count = 0;
while (n)
{
count++;
n = n & (n - 1);
}
return count;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = NomberOf1(n);
printf("%d\n", ret);
return 0;
}
总结
这道题主要考察了位运算符和二进制表示的知识。
最后感谢大家的阅读、点赞、评论。如果有什么问题和提问,可以在评论区提出呀。