Karatsuba算法-python实现-仅限于2的整数次幂输入

最近在学习Coursera上Stanford的algorithm课程,第一周是有关Karatsuba算法的,因而编写了一段python代码。需要说明和感谢的是https://blog.csdn.net/popoffpopoff/article/details/81903768
这位博主,我借鉴了他所写的代码的大部分,然而发现一个小问题,并进行了修正。
另外,所写的代码仍然是很局限的,仅限于2的整数次幂输入,限于目前水平,不想花过多时间进行研究,希望能有后人将这个继续研究下去。

# 这是我自己写的karatsuba算法,但是仍然有缺陷,比如万一是9位数,怎么办?但是现在网课赶进度,就没有细究了
def karatsuba(x,y):
    if len(str(x)) == 1 or len(str(y)) == 1:
        return x*y
    if len(str(x)) != len(str(y)):
        return x*y  # 事实证明这一句非常重要,即使原始输入是2的整数次幂,在计算过程中也可能出现123*21这一类非整的情况。不加这一句
    # 就会错。
    n = max(len(str(x)), len(str(y)))
    print("n", n)
    half = n//2
    print("half", half)
    x1 = x // 10 ** half  # 十位数
    print("x1", x1)
    x0 = x % 10 ** half  # 个位数
    print("x0", x0)
    y1 = y // 10 ** half  # 十位数
    print("y1", y1)
    y0 = y % 10 ** half  # 个位数
    print("y0", y0)
    z0 = karatsuba(x0, y0)
    print("z0", z0)
    z2 = karatsuba(x1, y1)
    print("z2", z2)
    z1 = karatsuba((x0+x1), (y0+y1)) - z0 - z2
    print("z1", z1)
    z = z2 * 10 ** n + z1 * 10 ** half + z0
    print("z", z)
    return z


c = karatsuba(12345678, 87654321)
print(c)

另外,在维基百科上竟然搜到了python代码实现,我相信肯定比我的更好,但是我也没花时间仔细研究了,因为看起来好像有点复杂,我也将代码贴上:

def karatsuba(num1, num2):
    num1Str, num2Str = str(num1), str(num2)

    if num1Str[0] == '-': return -karatsuba(-num1, num2)
    if num2Str[0] == '-': return -karatsuba(num1, -num2)  # 显然是来判断正负的,不过我很好奇为什么是两个负号,那岂不就白费了吗?

    if num1 < 10 or num2 < 10: return num1 * num2

    maxLength = max(len(num1Str), len(num2Str))
    num1Str = ''.join(list('0' * maxLength)[:-len(num1Str)] + list(num1Str))
    # Python join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
    num2Str = ''.join(list('0' * maxLength)[:-len(num2Str)] + list(num2Str))

    splitPosition = maxLength // 2
    high1, low1 = int(num1Str[:-splitPosition]), int(num1Str[-splitPosition:])
    high2, low2 = int(num2Str[:-splitPosition]), int(num2Str[-splitPosition:])
    z0, z2 = karatsuba(low1, low2), karatsuba(high1, high2)
    z1 = karatsuba((low1 + high1), (low2 + high2))
    return z2 * 10 ** (2 * splitPosition) + (z1 - z2 - z0) * 10 ** splitPosition + z0

c = karatsuba(12345678, 87654321)
print(c)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值