[容易]1.A+B問題

我是小小強(qiáng),這是我的第5篇原創(chuàng)文章,閱讀需要大約10分鐘。


題目

LintCode:A+B問題

描述

給出兩個(gè)整數(shù)ab, 求他們的和, 但不能使用+ 等數(shù)學(xué)運(yùn)算符。

  • 說明
    a和b都是 32位 整數(shù)么?
    是的
    我可以使用位運(yùn)算符么?
    當(dāng)然可以

樣例

如果a=1并且b=2,返回3

思路

題目要求不可以使用加減乘除四則運(yùn)算,那肯定是在移位或者位運(yùn)算上做文章。經(jīng)過分析,兩個(gè)整數(shù)ab的加法操作,可以等效于(a&b)<<1a^b相加,也就是進(jìn)位值和非進(jìn)位值,然后又可以繼續(xù)通過這種操作進(jìn)行運(yùn)算,直到達(dá)到一個(gè)不滿足的條件(也就是不在進(jìn)位)為止。這就可以借助循環(huán)或者遞歸操作,關(guān)鍵在于找到結(jié)束循環(huán)和遞歸的條件。對于a&b來說,顯然是有可能不在進(jìn)位,也就是值為0的,這就是一個(gè)有效的判斷條件。

實(shí)現(xiàn)

遞歸實(shí)現(xiàn)

  1. java代碼
class Solution {
    /*
     * param a: The first integer
     * param b: The second integer
     * return: The sum of a and b
     */
    public int aplusb(int a, int b) {
        // write your code here, try to do it without arithmetic operators.
        
        if(a == 0)
            return b;
        return aplusb((a&b)<<1, a ^ b);
    }
};
  1. 結(jié)果分析
    結(jié)果:結(jié)果通過了LintCode的要求。
    分析:這種遞歸只是單純兩個(gè)整數(shù)的操作,在若干次遞歸運(yùn)算之后,很快達(dá)到某個(gè)操作數(shù)為0的條件,從而結(jié)束遞歸。因此速度還是可以達(dá)到要求。

非遞歸實(shí)現(xiàn)

  1. java代碼
class Solution {
    /*
     * param a: The first integer
     * param b: The second integer
     * return: The sum of a and b
     */
    public int aplusb(int a, int b) {
        // write your code here, try to do it without arithmetic operators.
        
        int sum = 0;
        do {
            sum = a ^ b;
            a = (a & b) << 1;
            b = sum;
        } while ( a != 0 );
        
        return sum;
    }
};

2.結(jié)果分析
結(jié)果:結(jié)果通過了LintCode的要求。
分析:這種操作需要完全理解實(shí)現(xiàn)原理。加法,可以拆分成異或得到的“加法不進(jìn)位”相與左移1的進(jìn)位加法,因此,每次遞歸中都進(jìn)行異或、相與左移1,然后,將得到的結(jié)果再做同樣的操作,直到進(jìn)位為0,遞歸停止。

其它優(yōu)化參考

lintcode刷題 A + B 問題 位運(yùn)算

思路:
考慮一個(gè)普通的加法計(jì)算:5+17=22
在十進(jìn)制加法中可以分為如下3步進(jìn)行:
忽略進(jìn)位,只做對應(yīng)各位數(shù)字相加,得到12(個(gè)位上5+7=12,忽略進(jìn)位,結(jié)果2);
記錄進(jìn)位,上一步計(jì)算中只有個(gè)位數(shù)字相加有進(jìn)位1,進(jìn)位值為10;
按照第1步中的方法將進(jìn)位值與第1步結(jié)果相加,得到最終結(jié)果22。
下面考慮二進(jìn)制數(shù)的情況(5=101,17=10001):
仍然分3步:
忽略進(jìn)位,對應(yīng)各位數(shù)字相加,得到10100;
記錄進(jìn)位,本例中只有最后一位相加時(shí)產(chǎn)生進(jìn)位1,進(jìn)位值為10(二進(jìn)制);
按照第1步中的方法將進(jìn)位值與第1步結(jié)果相加,得到最終結(jié)果10110,正好是十進(jìn)制數(shù)22的二進(jìn)制表示。
接下來把上述二進(jìn)制加法3步計(jì)算法用位運(yùn)算替換:
第1步(忽略進(jìn)位):0+0=0,0+1=1,1+0=0,1+1=0,典型的異或運(yùn)算。
第2步:很明顯,只有1+1會(huì)向前產(chǎn)生進(jìn)位1,相對于這一數(shù)位的進(jìn)位值為10,而10=(1&1)<<1。
第3步:將第1步和第2步得到的結(jié)果相加,其實(shí)又是在重復(fù)這2步,直到不再產(chǎn)生進(jìn)位為止。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容