【万人千题】12.1算法:位与运算符
今天主要学习的是位与的运算符。
通过学习,我们可以发现位数上的数与上一个1是不会改变的。如,位上原本是1,与1还是1,是0,与1还是0.同理,与上0就会改变。
那么就有了一下几种用法:
1,奇偶性的判定
一般我们使用的是%2来判定。我们不妨对奇偶数的第一位二进制位分析一下。如果是偶数,那么第一位一定是0,因为二进制除了第一位都可以被2整除。而奇数的二进制第一位一定是0.那么运用这个特性我们就可以把偶数和奇数按位与上一个1。1除了第一位之外,其他全为0.而与上0,其他位不管是什么一定是0,就看第一位与的结果。如果第一位与的结果是1,就证明不是偶数,是0则是偶数。
2,只要或者除去某个数二进制的后几位数。
0b是二进制的符号。可以用0b111110.等
如一个二进制数n,11111111111111,我只要后5位.
那么这时候就可以用上与操作符了。直接让这个数n&0b11111,其他的位上自然就被改成0了。
除去的话,一般我们少位的就直接写出来如11111111111111只要后五位就直接&0b11111111100000,但一般也会转成16进制,四位一个,然后按位与一下就出来了。
3,2的幂的判定。
如果一个数是2的幂,那么它必然是只有一个位上有1,这时候,我们减一会如何呢?就是这个位上后面的位全变成1,然后这个位变成0;这时候两数相与就会发现是0,如果这个数与它减一的数相与之后不是0,那就不是2的幂
接下来来点习题练练把:
191. 位1的个数 - 力扣(LeetCode) (leetcode-cn.com)
//解法一:
int hammingWeight(uint32_t n)
{
int count=0;
int i=1;
while(n)
{
count+=n&1;
n=n>>1;
}
return count;
}
// //解法二:
// int hammingWeight(uint32_t n)
// {
// int count=0;
// while(n)
// {
// n&=n-1;
// count++;
// }
// return count;
// }
两种方法,一种将n拿到后,一个位一个位去与。第二种就直接与上n-1,每次n-1都相当于把最小位上的1给减掉,然后和原数相与之后就会没掉,这样每次进行一次操作就会消去一个1,就让count++就可以了,看看到底操作了几次。
剑指 Offer 15. 二进制中1的个数 - 力扣(LeetCode) (leetcode-cn.com)
//解法一:
// int hammingWeight(uint32_t n)
// {
// int count=0;
// int m=0;
// while(n!=0)
// {
// m=n%2;
// if(m==1)
// count++;
// n=n/2;
// }
// return count;
// }
//解法二:
int hammingWeight(uint32_t n)
{
int count=0;
while(n)
{
n&=n-1;
count++;
}
return count;
}
与上一题差不多。
1356. 根据数字二进制下 1 的数目排序 - 力扣(LeetCode) (leetcode-cn.com)
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int cmp(const void*e1,const void*e2)
{
int count1=0;
int count2=0;
int i=*(int*)e1;
int j=*(int*)e2;
while(i)
{
i&=i-1;
count1++;
}
while(j)
{
j&=j-1;
count2++;
}
if(count1==count2)
return *(int*)e1-*(int*)e2;
if(count1>=count2)
return 1;
else
return 0;
}
int* sortByBits(int* arr, int arrSize, int* returnSize)
{
qsort(arr,arrSize,sizeof(int),cmp);
*returnSize=arrSize;
return arr;
}
关键在于排序的规则。我们用上qosrt,然后自己写排序规则。进来排序的两个数分别赋给一个变量,然后两个变量分别去求他们的二进制位上1的个数,如果大于就直接排,相等的情况另外处理即可。
762. 二进制表示中质数个计算置位 - 力扣(LeetCode) (leetcode-cn.com)
bool Isprime(int n)
{
if(n==1)
return false;
int i=2;
for(;i<=sqrt(n);i++)
{
if(n%i==0)
return false;
}
return true;
}
int countPrimeSetBits(int left, int right)
{
int i=left;
int countsum=0;
for(;i<=right;i++)
{
int count=0;
int j=i;
while(j)
{
j&=j-1;
count++;
}
if(Isprime(count))
countsum++;
}
return countsum;
}
只是找出二进制中1的个数,判断这个个数是不是素数,多写一个素数判断就可以了。
231. 2 的幂 - 力扣(LeetCode) (leetcode-cn.com)
//解法一:
// bool isPowerOfTwo(int n)
// {
// double i=log2(n);
// if(i==(int)i)
// return true;
// else
// return false;
// }
//解法二:
bool isPowerOfTwo(int n)
{
if(n<=0)
return false;
if(n&(n-1))
return false;
return true;
}
上面判断2的幂用上即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了