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

 

 

 

 

 

 

 

 

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