越过寒冬
前言
今天复习了一些操作符的知识,看到了这道题,并且发先有三种解题思路,觉得有趣,据记下来与诸位分享一下。
题目
写一个函数,给定一个整数,求他的二进制位中1的个数
思路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;
}
思路2
我们还可以用“/”,和“%”来代替右移操作符即>>
但是要注意,把函数的参数设置为无符号数,因为如果是负数的话要是用有符号数接受就会算不出来
#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是否++。
总结
当涉及到二进制时就要想到按位操作符,右移左移操作符了,同时也可以在有时间的情况下探索一下是否有更多思路。今天的分享就到这里啦,觉得有帮助就点个赞支持一下吧,谢谢!