美文网首页
lintCode题解 (1)

lintCode题解 (1)

作者: Sivin | 来源:发表于2018-04-27 16:08 被阅读36次

    标签(空格分隔): lintCode


    题目: 给出两个数A,B 在不使用加法运算的符的情况下,计算 AB的和

    输入 A = 1, B = 3 ,sum = 4;

    分析:这道题其实考察的就是计算机中两个数如何实现加法运算, 也就是加法器的实现原理.计算机中数字是以二进制的方式存放的.两个数使用+进行相加时,我们从二进制上看是这样的

    0 0 0 1 ----1
    0 0 1 1 ----3
    ———— + ———
    0 1 0 0 ----4
    

    这里我们看到,低位先加,如果产生进位,则高位加上低位的进位在相加.这与我们十进制相加的原理一样.

    我们十进制相加时,遇十进一,二进制相加时,遇二进一,这是我们人的计算理论,然而计算机却不是这样,计算机的运算是数字逻辑电路实现的,是,,门电路实现的.

    对于一位二进制运算:

    A   B   result
    0 + 0  =  0;
    1 + 1  =  0;
    1 + 0  =  1;
    0 + 1  =  1;
    

    我们可以总结出这样的规律:

    result = A ^ B
    

    这个规律对于多位二进制运算基本上也是适用的;对于下面的一个例子我们看看

    0 1 0 1 ----5
    1 0 1 0 ----10
    ——— ^ ——— --- (按位做异或运算)
    1 1 1 1 --- 15
    

    但是不总是适用,对于每一位都不产生进位的情况下,我们可以得到正确的结果,那么如果产生进位呢?

    0 0 1 0 1 ----5
    0 1 0 1 1 ----11
    ——— ^ ——— ---  (按位做异或运算)
    0 1 1 1 0 --- 14 (实际结果)
    1 0 0 0 0 --- 16 (期望结果)
    

    这就不对了,为什么呢?因为我们没有加上进位,如果我们加上进位就行了.

    对于上面的计算进位产生在第一位(最右边),因此我们需要在第二位上加1,
    于是计算的过程需要在一次做加法计算,我们使用同样的方式进行

    0 1 1 1 0 --- 14 (上一步的结果)
    0 0 0 1 0 --- 2(上一步的进位)
    ——— ^ ——— ---  (按位做异或运算)
    0 1 1 0 0 --- 12 (实际结果)
    1 0 0 0 0 --- 16 (期望结果)
    

    我们发现还是不对,因为加上进位后,第二位又产生了进位,结果又不对了,我们一次在进行加上进位计算

    0 1 1 0 0 --- 12(上一步的结果)
    0 0 1 0 0 --- 4(上一步的进位)
    ——— ^ ——— ---  (按位做异或运算)
    0 1 0 0 0 --- 8 (实际结果)
    1 0 0 0 0 --- 16 (期望结果)
    

    还有进位产生,再次进行运算

    0 1 1 0 0 --- 8(上一步的结果)
    0 1 0 0 0 --- 8(上一步的进位)
    ——— ^ ——— ---  (按位做异或运算)
    0 0 0 0 0 --- 0 (实际结果)
    1 0 0 0 0 --- 16 (期望结果)
    

    结果产生了进位,在一次加上进位计算

    0 0 0 0 0 --- 0(上一步的结果)
    1 0 0 0 0 --- 16(上一步的进位)
    ——— ^ ——— ---(按位做异或运算)
    1 0 0 0 0 --- 16 (实际结果)
    1 0 0 0 0 --- 16 (期望结果)
    

    没有进位产生了,结果也正确了.

    我么发现,如果没有进位产生 sum = A ^ B这个sum就是AB的和,如果产生了进位,则需要在其基础上加上进位,再次运算.于是问题,就转换成了判断每一次结果是否产生了进位的问题.

    如何判断两个数在相加时是否有进位产生呢?

    这个问题我们可以求解其对立面,我知道两个数如果相加没有进位产生,这个很简单,类似于下面

    对应位上的数不会同时出现`1`
    0 1 0 0 1 
    1 0 1 0 0 
    

    也就是说 A & B是等于0的,这样就可以判断这两个数没有进位产生,如果不等于0则必有进位产生.

    解决了进位产生的问题,我们还需要知道进位是多少,这个问题也很简单,只要有进位产生,我们就需要将前一位加1,
    于是我们不难发现进位C可以这样表示

    C = (A & B) << 1;
    

    这样我们就将问题全部分析完毕了.

    写一下代码实现

    long aPlusb(long a , long b){
        long sum = 0;
        long temp = a & b;
        sum = a ^ b;
       if(temp = 0){ //没有进位产生
            return sum;
       }
       //有进位产生,返回加上进位的结果
       return aPlusb(temp<<1,sum);
    }
    
    

    相关文章

      网友评论

          本文标题:lintCode题解 (1)

          本文链接:https://www.haomeiwen.com/subject/jsxilftx.html