[劍指Offer]面試題65:用加減乘除做加法

寫一個函數,求兩個整數之和,要求在函數體內不得使用 “+”、“-”、“*”、“/” 四則運算符號。
示例
輸入: a = 1, b = 1
輸出: 2
提示
a, b 均可能是負數或 0
結果不會溢出 32 位整數
思路

  • 和題目64類似,不能使用四則運算,自然就想到了位運算,即實現二進制的加法運算,學過計算機組成與結構的應該很容易理解。
  • 對於二進制加法來說,首先個位的2個數字相加,得到了一個和,一個進位,然後再計算十位,直到進位爲0,加法結束。
  • 首先,求和,兩個數字相加時和異或運算相同
  • 齊詞,得到進位,二進制只有1+1會產生進位,因此,可以將兩個數字做位與運算,然後左移
  • 最後,重複前兩步,直到不再產生進位

題目中說明a,b可能是負數,而且結果不會超過32位,因此,需要知道python中的負數編碼。
Python 負數的存儲
Python/Java 中的數字都是以補碼形式存儲的。但Python沒有int, long等不同長度變量,即沒有變量位數的概念。
獲取負數的補碼:需要將數字與十六進制數0xffffffff相與。可理解爲捨去此數字32位以上的數字,從無限長度變爲一個32位整數。
返回前數字還原:若補碼aa爲負數(0x7fffffff是最大的正數的補碼),需執行~(a^x) 操作,將補碼還原至Python的存儲格式。a^x運算將1至32位按位取反;~運算是將整個數字取反;因此,~(a^x)是將32位以上的位取反,即由0變爲1,1至32位不變。
代碼

# LeetCode
# 常規解法
class Solution:
    def add(self, a: int, b: int) -> int:
        x = 0xffffffff
        a, b = a & x, b & x
        while b != 0:
            a, b = (a ^ b), (a & b) << 1 & x
        return a if a <= 0x7fffffff else ~(a ^ x)
# 非常規解法
class Solution:
    def add(self, a: int, b: int) -> int:
       return sum([a,b])

參考:
https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/solution/mian-shi-ti-65-bu-yong-jia-jian-cheng-chu-zuo-ji-7/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章