Karatsuba乘法的算法思路运用了递归的思想,贴上Stanford的Tim Roughgarden的课件。这里说说我遇到的代码实现的问题。Karatsuba Multiplication 在Python中实现的问题

在coursera上面的算法课的作业题是用这个Karatsuba做两个64位整数相乘。

我最开始写的代码:

import numpy as np

def Karatsuba(x,y):
    m=(len(str(x))//2)
    a = x // (np.power(10, m))
    b = x % np.power(10, m)
    c = y // (np.power(10, m))
    d = y % np.power(10, m)

    if len(str(x))==1:
        return x*y
    else:
        a_c = Karatsuba(a,c)
        b_d = Karatsuba(b,d)
        ad_bc = Karatsuba(a+b,c+d) - a_c - b_d

        res = np.power(10,m*2) *a_c +np.power(10,m)*ad_bc + b_d

        return res

当输入不太大的时候,例如8位或者16位整数,代码实现没有问题,但是当输入为64位数的数字时,代码就会报错,如

RecursionError: maximum recursion depth exceeded while calling a Python object

或者

RuntimeWarning: overflow encountered in long_scalars.

问题在于实现10^n次方时选择numpy.power(10,n), 需要修改为10**n,正确的代码如下:

def Karatsuba(x,y):
    m=(len(str(x))//2)
    a = x // 10 ** m
    b = x % 10 ** m
    c = y // 10 ** m
    d = y % 10 ** m

    if len(str(x))==1:
        return x*y
    else:
        a_c = Karatsuba(a,c)
        b_d = Karatsuba(b,d)
        ad_bc = Karatsuba(a+b,c+d) - a_c - b_d
        res = 10**(2*m)*a_c + 10**m*ad_bc +b_d
        return res

同样的,我之前也尝试过用math.pow(10,n)来表示10的n次方 ,在递归时输入太大也会报错。

所以总结就是多用10**n,其次numpy.power(10,n)【因为内置函数是c语言实现的,比较快】,最次math.pow(10,n)。

大家可以练习一下啦~ (有错欢迎纠正指教~)

输入:

s1=3141592653589793238462643383279502884197169399375105820974944592
s2=2718281828459045235360287471352662497757247093699959574966967627

你的输出是多少呢? 

(PS:其实在python中输入s1*s2 就可以直接得到正确答案, 可以和自己的代码结果比较)

 

 

 

相关文章: