1. 程式人生 > >不用加法求兩數之和

不用加法求兩數之和

640?wx_fmt=png&wxfrom=5&wx_lazy=1

1

大家好,我叫阿美

是一名帝都女演算法工程師

2

大家好,我叫阿毛

是一名混日子的帝都男後端

640?wx_fmt=png&wxfrom=5&wx_lazy=10?wx_fmt=png

3

阿毛,咱倆做同事那麼久了,出個問題考考你唄,如果你能回答上來,給你一個請我吃飯的機會

4

阿美,好呀,好呀,什麼問題?追了你那麼久,都沒答應跟我吃一頓飯,非常期待呦!

0?wx_fmt=png0?wx_fmt=png

3

不用加法,求出兩個整數之和

4

我想了半天,也沒想出答案,不用加法還想求出兩個數之後,你這是故意不給我機會請你吃飯呀

0?wx_fmt=png0?wx_fmt=png

5

阿毛,這麼簡單的不用加法求和運算,你都回答不上來,平常的演算法是怎麼學的,就這還想追我!

4

阿美,其實,我挺努力的,不過我平常是做後端應用的,對演算法認識不夠深刻,要不,你教教我

0?wx_fmt=png0?wx_fmt=png

5

好吧,阿毛,先給你講講或運算!

6

回想一下『或』這個詞在數學裡的意思——『一個元素在集合A或集合B裡』意味著『它只在A裡』、『它只在B裡』、『它在A和B的交集裡』這三種情況中的一種。

0?wx_fmt=png

7

阿美,喔喔,我明白了,這就是或運算的邏輯圖呀,紅色區域就是代表了A||B,不過這和兩個數相加有啥關係呢?

0?wx_fmt=png0?wx_fmt=png

8

阿毛,上面給你講了或運算,確實和兩個數相加沒有關係,只是為了給你講異或運算,讓你更明白!

9

『異或』不允許『共存』的情況,所以把A且B的那一部分除掉!

0?wx_fmt=png

10

喔喔,阿美,這就是異或運算呀,我是不是可以這樣理解,A和B相同的部分為假,所以去掉,A和B不同的部分為真,所以保留!

0?wx_fmt=png0?wx_fmt=png

11

是呀,阿毛,異或運算的口訣就是,同為假,異為真!,所以0和1的異或運算如下:0^0 = 0, 

     1^0 = 1, 0^1 = 1,1^1 = 0

再看看0和1的二進位制加法,

不考慮進位:1+1=0,

1+0=1,0+1=1,0+0=0,

阿毛,你看在不考慮進位的時候,加法可以用異或實現

12

哇,阿美,還真是這樣呢,你不這樣對比,我還真沒發現加法和異或還有這樣的關係

0?wx_fmt=png0?wx_fmt=png

13

阿毛,現在要考慮有進位的情況啦~!還是先看加法吧:0+0進位是0,

1+0、0+1進位是0,1+1進位是1,

再看看與運算:0&0=0;   0&1=0;    1&0=0;     1&1=1;阿毛,你發現了麼?在考慮進位運算時,加法和&運算類似呦

14

噗!我聽你講了異或運算^和與運算&,還沒有聽懂怎麼不用加法,求出兩個數之和呢?

0?wx_fmt=png0?wx_fmt=png

15

阿毛,你怎麼那麼笨呀,

那麼加法運算可以這樣實現:

1)先不考慮進位,按位計算各位累加(用異或實現),得到a;

2)然後計算進位,並將進位的值左移,得到值b。b0,則a

就是加法運算的結果;b不為0,則a+b即得結果(遞迴呼叫這個過程)。實現演算法如下:

public int bitAdd(int a,int b )
{
if(b==0)
{
return a;
}
int sum=a^b;
   int carry=(a&b)<<1;
   return bitAdd(sum,carry);
}

1661166

哇!阿美,你不僅長的這麼漂亮,還這麼聰明呢,以前也學過位運算,但是還真沒發現它和加法有這麼神奇的關係呢!話說,還有機會請你吃飯麼?

0?wx_fmt=png

走,吃飯去!

0?wx_fmt=png

推薦閱讀:

覺得有幫助?請轉發給更多人!

0?wx_fmt=png0?wx_fmt=png

架構師小祕圈,聚集10萬架構師的小圈子!不定期分享技術乾貨,行業祕聞!彙集各類奇妙好玩的話題和流行動向!長按左側圖片,掃碼加入架構師微信群!