你真的会 &与运算妙用吗?

文章目录

  • 求取多少1
  • 再来个进阶版 & 运算
  • 更高级进阶
  • 最后一个小技巧 n&1

求取多少1

输入一个整数,求该整数二进制格式有多少位是1

输入: 22

输出: 3

输入:251

输出:7

运用原理: n & (n-1)

比如: 16 与 16-1

  • 10000(二进制16)
  • 01111(二进制15)

16&15 的结果就是0. 发现什么了?? 抵消了数字16二进制的倒数第一个1.

下面我们以251画图演变:

你真的会 &与运算妙用吗?_第1张图片

  • 其实减1的作用就是为了让二进制最后一个1的后面全部为0,利于相&计算.

上代码:

#include 
int main()
{
     
    int n = 0,count = 0;
    scanf("%d", &n);
    while(n)
    {
     
        n = n&(n-1);
        count++;
    }
    printf("该数字有%d个1",count);
    return 0;
}


再来个进阶版 & 运算

输入一个整数n,判断n是不是2的次方. 是输出1,否则输出0

输入:16

输出:1

输入:9

输出:0

输入:32

输出:1

原理:还是 n&(n-1)

记得上面那个题我说的n-1的作用是什么吗? 把二进制中的最后一个1的后面全部变为0.

比如1000(十进制8) - 1 = 0111;

而2进制的每位的权重就是2的次方,比如1011换算成十进制 1x2³ + 0x2² + 1x2¹ + 1x2º = 11

所以2的次方的二进制只能有一个1,且在最高位,比如:

  • 10000 (2的4次方 16)
  • 100000(2的5次方 32)

那么只要 n&(n-1)的结果是0,就说明n是2的次方

#include 
int main()
{
     
    int n = 0;
    scanf("%d", &n);
    int ret = 0;
    
    ret = (n & (n - 1)) == 0 ? 1 : 0;   //博主运用的条件表达式,大家也可以用if判断
    
    printf("%d\n", ret);
    return 0;
}


更高级进阶

输入两个整数,求两个整数二进制中相同位置不同数字的位置有多少个?

输入: 22 33

输出: 5

输入:1999 2299

输出:7

解析:

题目要求的是求相同位置不同数字的位置数量,那我们是不是可以把相同的数字全部转化为0??(用 ^ 或运算)

剩下的就是不同的数字了,然后就是消去 1 .用 n&(n-1)

以22 33为例. 请看图:

你真的会 &与运算妙用吗?_第2张图片

而统计多少个1,不就是最开始那个题吗?

#include 
int main()
{
     
    int n,m;
    scanf("%d%d",&n,&m);
    int ret = n ^ m;
    int count = 0;
    while(ret)
    {
     
        ret = ret&(ret - 1);
        count++;
    }
    printf("不同的位有%d个", count);
    return 0;
}

最后一个小技巧 n&1

那么大家猜猜 这个用来干嘛的?对,判断整数n是不是奇偶
原理:

  • 奇数的二进制末尾一定是1
  • 偶数的二进制末尾一定是0
    而1的二进制是00000000001等,前面全是0,也就是说一个数与1进行&运算,实际运算的只有1位,那就是末位数字0或1(仔细去想想是不是).

所以,如果 n&1为真,就是奇数
否则偶数

你可能感兴趣的:(题解,c)