越过寒冬
今天复习了一些操作符的知识,看到了这道题,并且发先有三种解题思路,觉得有趣,据记下来与诸位分享一下。
题目
写一个函数,给定一个整数,求他的二进制位中1的个数
既然是二进制位那自然是想到了按位与按位或他们几个
可以这样写
因为整形是32个比特位,所以for循环32次,通过&1判断出当前最后一位是否为1,通过>>i不断调整最后一位,直到32位全部检查完毕
#include<stdio.h>
int counts(int a)
{
int num = 0;
for(int i=0;i<32;i++)
if((a >>i)&1)
num++;
return num;
}
int main()
{
printf("%d",counts(20));
return 0;
}
我们还可以用“/”,和“%”来代替右移操作符即>>
但是要注意,把函数的参数设置为无符号数,因为如果是负数的话要是用有符号数接受就会算不出来
#include<stdio.h>
int counts(unsigned int a)
{
int num = 0;
while (a)
{if (a % 2)
num++;
a /= 2;
}
return num;
}
int main()
{
printf("%d",counts(-1));
return 0;
}
这个思路就很巧妙了
我们首先发现n&=(n-1)可以把n二进制位最右边的1改为0
于是有思路
#include<stdio.h>
int counts( int a)
{
int num = 0;
if (a)
num++;
while (a & (a - 1))
{
a &= (a - 1);
num++;
}
return num;
}
int main()
{
printf("%d",counts(3));
return 0;
}
但是在这里,我们把num的值分了情况判断是否++,为什么呢
举个例子就好了:
传个2进去,则2&(2-1)==0,可是2的二进制位里有一个1,所以,懂了吗,要先个他赋值为1
可是还有一个特殊情况----传参为0时,于是要先判断传参是不是0,在决定num是否++。
当涉及到二进制时就要想到按位操作符,右移左移操作符了,同时也可以在有时间的情况下探索一下是否有更多思路。今天的分享就到这里啦,觉得有帮助就点个赞支持一下吧,谢谢!