【前言】
今天是力扣打卡第15天!
天天做遞回做煩了,換換腦子,嘿嘿,

原題: 不用加減乘除做加法
題目描述:
寫一個函式,求兩個整數之和,要求在函式體內不得使用 “+”、“-”、“*”、“/” 四則運算子號,
示例:
輸入: a = 1, b = 1
輸出: 2
題解:
如果是十進制的話,我們如何完成加法計算呢?
比如99 + 111 = ?
第一步:計算進位的數字:
1 + 9 = 10;
10 + 90 = 100;
得到進位結果:110第二步:個、十、百位 的數字分別相加先不管進位的問題:
個位:9 + 1 = 0
十位:9 + 1 = 0
百位:0 + 1 = 1
得到臨時結果:100第三步:相加得到結果:
100 + 110 = 210
如何用二進制完成以上的步驟呢?
問題1: 二進制的加法利用以上的步驟可以得到正確的結果嗎?
12 二進制:1100
15 二進制:1111第一步:計算進位的數字:
0100 + 0100 = 1000
1000 + 1000= 10000
得到進位結果:11000第二步:做不進位加法
1100 + 1111 = 0011
得到臨時二進制結果:0011第三步:將第一步和第二步結果相加得到答案
0011 + 11000 = 11011(十進制:27)
就目前來看,是可以的,問題2:第一步驟不用加法如何得到相同結果?相與并且左移一位
如果相&能得到1 ,那么表示,對應位置上的數字都是1,然后再往左移動一位,就是步驟一 進位得到的結果(1100 & 1111) << 1 = 11000
問題3:第二步驟不用加法如何得到相同結果?異或(俗稱不進位加法)
異或:相同為0,相異為11100 ^ 1111 = 0011
問題4:第三步驟不用加法如何得到相同結果?其實這是個套娃
第三步不用加法實作最難,因為第三步是前兩步的和,還是個加法;如果不用加法,就只能不斷呼叫前兩步的步驟,但是這里難想的是什么時候停下來呢?
當不再需要進位就代表停止了,即進位的結果是0的時候停止
代碼執行:
int add(int a, int b){
//因為不允許用+號,所以求出異或部分和進位部分依然不能用+號,所以只能回圈到沒有進位為止
while(b){
//保存進位值,下次回圈用
int c = (a & b) << 1;
//保存不進位值,下次回圈用
a = a ^ b;
b = c;
}
//如果還有進位,再回圈,如果沒有,則直接輸出沒有進位部分即可
return a;
}
Q : 若數字 a 和 b 中有負數,則變成了減法,如何處理?
A : 在計算機系統中,數值一律用 補碼 來表示和存盤,補碼的優勢: 加法、減法可以統一處理(CPU只有加法器),因此,以上方法 同時適用于正數和負數的加法
結語
今天是力扣打卡第15天!
我想吐槽一下,這道題在力扣上面顯示的是“簡單”,但是我硬生生沒想出來怎么做,嗚嗚嗚,多虧力扣上面的大佬們,抱拳了,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/357046.html
標籤:其他
