LeetCode:43 multiply 大數乘法的數學直觀理解

 

leetcode上遇到的題。

我們學了那麼多年的數學,做了那麼多年的乘法,卻不曾仔細總結其中的規律,至少是沒有用這種程序化的邏輯概括過。

這個計算過程想想也是很有意思,還是總結下。

以15*15=225爲例:

個位數是5*5=25,留5,進位2.

十位數稍微複雜點,有兩個乘法都是以他爲底,並且他還可能從個位得到進位,還需要進位給百位。

百位至少在本例簡單點,1*1是不用再進位了,但是也需要從十位得到一次進位。

 

所以15*15=225的乘法流程總結起來就是,從輸出結果的角度,以每個位(k)去找對應的以他爲底的乘法計算,直觀的說,k=1時(十位),前者的10乘以後者的5,後者的10乘以前者的5,他們是共享底位(十位)的。50+50=100,算上25進的那個20,結果就是120,120的1進給百位,百位的10*10=100,加上進位的100,就是200。每個位都得到,最後225。

其實總的來看,有點像二項式展開的意思。核心思想:你可以給每位一次性計算出所有結果並累加,然後進位,算其他位。

 

時間關係,不做圖囉嗦了,在紙上寫一下基本的乘法計算過程,很容易看出來,其他註釋寫到代碼中:

class Solution:
    def multiply(self, num1, num2):
        if num1 == '0' or num2 == '0':#有0就不用乘了。
            return '0'
        res = ''
        carry = 0#初始化
        # 兩個數的長度,分別都減1
        m = len(num1) - 1
        n = len(num2) - 1
        # m和n都是len減1,是因爲,15*15中,不算被動進位,能用來主動計算乘法的,最高位就是百位,10*10=100,是主動計算的最高位。
        # k就在[0,m+n]的區間:代表主動計算乘法的位(最後多出來的進位單獨給出)。k=0,i和j都是0,5*5,對應個位結果。
        # k=1,i和j分別是0、1和1、0組合,是10和5或者5和10,對應十位的結果,
        # k=2,i和j分別是1、1(其他組合不滿足篩選條件,我計算的就是百位,不能把5也拿來用吧,把乘法寫一下就出來了),代表10和10相乘,對應百位結果。
        for k in range(m + n + 1):
            print('k:',k)
            # i是所有輸出位,包括k=m+n,不包括m+n+1,其實就是遍歷所有可能的num1和num2的單獨一位,做一個總的累加
            # i、j他倆是嚴格針對k的互補關係。i = 時,j = 1;i = 1時,j = 0,他們都對應結果的“下標”k=1,也就是“十位”
            sum = carry#先把進位計算進來(這個順序其實無所謂,但是如果不是先進位,就要給sum清零了)
            for i in range(k + 1):#k其實就是結果位。i和j是根據k做的互補,嚴格對應一個結果底位。
                j = k - i
                if i <= m and j <= n:
                    index_i = m - i# 轉換,字符串形式,i=0其實代表的是最大的那個數,不是最小的,index_i纔是最小的數。
                    index_j = n - j
                    sum += int(num1[index_i]) * int(num2[index_j])#
            # 拼接結果字符串,遍歷完當前k對應的所有i和j的組合,當前位的結果已經出爐,可以拼接了。比如15*15的最後一位5*5,是由當前位停留結果5和進位2組成的,當前結果就留在這。
            res = str(sum % 10) + res#從低位向高位迭代,使用新的sum模,後加res的拼接方式。
            carry = sum // 10#進位,5*5=25,進位2

        if carry:#最後一位了,k迭代的是乘法計算,當然可能發生進位,比如33*44中,k是0到2,最高位3*4肯定要進位的
            res = str(carry) + res
        return res

 

 

 

 

 

 

 

 

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