1. 程式人生 > >lintcode第一題 a+b

lintcode第一題 a+b

問題描述

給出兩個整數 aa 和 bb , 求他們的和, 但不能使用 ++ 等數學運算子。

說明

a和b都是 32位 整數麼?

  • 是的

我可以使用位運算子麼?

  • 當然可以

樣例

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

挑戰

顯然你可以直接 return a + b,但是你是否可以挑戰一下不這樣做?


——————————題目分割線——————————

既然提示位運算了,那理所當然的要用位運算解決。正好複習一下位運算操作。
先來看看我們經常用到的位運算子:&(按位與)、| (按位或)、^(按位異或)、~(按位取反)、>>(按位右移)、<<(按位左移)。
要實現a+b,要用到什麼呢。
試個例子看看吧
5+7 = 101 + 111 = 1100 = 12

額,這裡好像有兩種思路,一種是一位一位看,考慮進位的話,一共有2^3種組合,a+b為

輸入輸出

前一位進位c-ab產生進位c+當前位結果d
00000
00101
01001
01110
10001
10110
11010
11111
啊,看著頭大,怎麼通過這個表得出輸出和輸入的關係的那個推導方式好像是數字邏輯裡的內容,我早就還給老師了,但是能觀察出來d = a^b^c-。
還是考慮整體方法吧。
思路2:把當前位和進位分開看,當前位的結果可以通過a^b得到,進位可以通過a&b得到,把進位左移一位再和當前位結果相加,利用遞迴呼叫,就能得到應得的結果。

嗯,這個思路明確,改成程式碼

int aplusb(int a, int b) {
	if ((a&b) == 0)
	{
		return a ^ b;
	}
	else
	{
		aplusb((a&b) << 1, a^b);
	}
程式碼似乎額外的簡單啊

提交也通過了,但是還有點小問題,定義a,b的是int,但是沒有報錯,思考一下可能是測試集範圍或者是伺服器是32位伺服器導致int取值變大了吧

忽然想到當年學c的時候老師隨口說的,一些大公司面試題喜歡出大數相乘,現在想想似乎就可以通過位運算來求解