zoukankan      html  css  js  c++  java
  • “A + B”竟然还能这样做?

    首先我们来看一下这道题目:

    相信许多人对这道题目并不陌生,在刚开始学习编程的时候,我们总能在习题库中看到它,如何解决呢,代码很简单:

    #include <stdio.h>
    int main()
    {
        int a, b;
        scanf("%d %d", &a, &b);
        printf("%d
    ",a+b);
        return 0;
    }

    但今天在逛博客的时候发现了领扣的一道有意思的题目,不使用加法运算符,计算a+b的值?

    作为一名初学者,我对此题毫无思路,但后来在思考的过程中,我想到了一种特殊的运算符 ——位运算

    那么,用位运算,这道题目该怎么解决呢?别着急,咱们接着往下看。

    首先,需要认识四个位运算符(大佬请无视)

    &:    按位与运算, 使参与运算的两数各对应的二进位相与,只有对应的两个二进制位均为1时,结果才为1,否则为0.

      举个栗子:a = 1, b = 2;

            a & b =  0001 & 0010 = 0000  = 0

    ^:     按位异或运算,使参与运算的两数各对应的二进位相异或,当两对应的二进位不同时,结果为1,否则为0.

      举个栗子:a = 9, b = 5;

            a ^ b = 00001001 ^ 00000101 = 00001100 = 12;

    << :   左移运算符:左移n位就是乘以2的n次方,作用是把“<<”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0。

      举个栗子:    3 << 4

             00000011 <<  4  =  00110000 = 48; 

    >> :   右移运算符:   右移n位就是除以2的n次方,  作用是把“>>”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数.

       举个栗子:   15  >> 2   =  00001111 = 00000011;        

     好,了解完基础知识过后,咱们开始正式解题:

      首先,咱们观察一下,1 ^ 0 = 1, 1 ^ 2 = 3, 

                 2 ^ 3 = 1,

                 3 ^ 4 = 7,

                 4 ^ 5  = 1, 5 ^ 6 = 3, 6 ^ 7 =  1,

                 7 ^ 8 = 15 ... ... ... ...

      采用异或进行运算,通过这几组测试,多多少少有一些不合群的,得不到正确的结果,

      分析一下 2 ^ 3 = 0011 ^ 0010 = 0001,如果第二位变成1,那就变为5了

           4 ^ 5 = 0100 ^ 0101 =  0001,第一位变成1,那不就变成9了

      慢慢总结就会发现,其实它存在着一定的进位关系: 

            那么加法运算可以这样实现:

      1)先不考虑进位,按位计算各位累加(用异或实现),得到值a;

      2)然后在考虑进位,并将进位的值左移,得值b,若b为0,则a就是加法运算的结果,若b不为0,则a+b即得结果(递归调用该函数)。

      代码如下:

    int add(int a, int b)
    {
        if(b == 0)
            return a;
        int c = a ^ b;
        int j = (a & b) << 1;
        return add(c, j);
    }

       参考:

     位运算 --- 百度百科     https://baike.baidu.com/item/%E4%BD%8D%E8%BF%90%E7%AE%97/6888804?fr=aladdin

     博客: https://www.cnblogs.com/houjun/p/4908725.html

       

  • 相关阅读:
    牛客挑战赛45 D.坐标
    树上启发式合并(dsu on tree)合集
    2020HDU多校第二场 1012.String Distance
    2020HDU多校第一场 1009.Leading Robots
    2020牛客暑期多校训练营(第一场)H.Minimum-cost Flow
    自用综合线段树模板(区间加乘、区间置数、区间求和)
    ZOJ 4008.Yet Another Tree Query Problem(问题模型转化+线段树离线处理)
    最小费用最大流模板
    2020 CCPC Wannafly Winter Camp Day3.C. 无向图定向(k染色问题)
    2020牛客寒假算法基础集训营3.E.牛牛的随机数(数位dp拆位算贡献)
  • 原文地址:https://www.cnblogs.com/PlayfulBlueMoon/p/12482974.html
Copyright © 2011-2022 走看看