【万人千题】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的幂用上即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值