版权声明:原创不易,本文禁止抄袭、转载,侵权必究!
目录
- 一、Karatsuba 乘法
- 二、算法思路
- 三、Python算法实现
- 四、作者Info
 
一、Karatsuba 乘法
当你在纸上做两个数字的乘法时,一般我们都是用小时候学到的方法:
 
 
这个计算方式的时间复杂度是 O(n²),但有没有其他的方法加速相乘的计算速度呢?
 Karatsuba 乘法是一种快速乘法。此算法在1960年由 Anatolii Alexeevitch Karatsuba 提出,并于1962年得以发表。此算法主要用于两个大数相乘。普通乘法的时间复杂度是O(n²),而 Karatsuba 算法的复杂度仅为O(3nlog2(3))
二、算法思路
可以注意到 AD +BC 这个计算需要两个 O(n²/4) 的乘法和一个 O(n) 的加法。
 (A+B)(C+D)-AC-BD = AC+AD+BC+BD-AC-BD = AD + BC
 Karatsuba 把这个原始的计算改成上面这个计算,因为 AC 和 BD 是已知的,因此现在的 AD +BC 的时间复杂度变成了 一个 O(n²/4) 的乘法和四个 O(n) 的加法或减法,达到 O(n^log2(3)) 的时间复杂度
三、Python算法实现
import numpy as np
from itertools import zip_longest
def add(x, y):
  z, carry = [], 0
  for r, s in zip_longest(x, y, fillvalue=0):   #以元素多的为基准,少的填充0
    t = r + s + carry
    carry = t // 10   #除法取整
    z.append(t % 10)  #取余
  if carry:
    z.append(carry)
  return z
def sub(x, y):
  z, carry = [], 0
  for r, s in zip_longest(x, y, fillvalue=0):
    t = r - s + carry
    carry = t // 10
    z.append(t % 10)
  return z
def karatsuba(x, y):
  # 确保长度相同
  while len(x) < len(y):
    x.append(0)
  while len(x) > len(y):
    y.append(0)
  # 长度和分割
  n = len(x)
  n_2 = (n + 1) >> 1
  # 长度等于1的情况
  if n == 1:
    return add([x[0] * y[0]], [])
  # 分割后进行赋值
  x0, x1 = x[:n_2], x[n_2:]
  y0, y1 = y[:n_2], y[n_2:]
  # karatsuba algorithm
  z0 = karatsuba(x0, y0)
  z1 = karatsuba(x1, y1)
  z2 = karatsuba(add(x0, x1), add(y0, y1))
  z2 = sub(sub(z2, z0), z1)
  z = add(z0, [0] * (n_2 << 1) + z1)
  z = add(z, [0] * n_2 + z2)
  return z
x, y = '53568757', '82567936'
def mult(x, y):
  print(x, '*', y, '=', int(x) * int(y))
  x = list(map(int, reversed(x)))
  y = list(map(int, reversed(y)))
  z = karatsuba(x, y)
  print(''.join(map(str, reversed(z))))
mult(x,y)
输出结果:
 
 如图所示,输出结果正确
四、作者Info
Author:小鸿的摸鱼日常,Goal:让编程更有趣!
专注于算法、爬虫,游戏开发,数据分析、自然语言处理,AI等,期待你的关注,让我们一起成长、一起Coding!
版权说明:本文禁止抄袭、转载 ,侵权必究!



![[Date structure]时间/空间复杂度](https://img-blog.csdnimg.cn/9234b44878814ac3b295f50ef7a07024.png)














