Copyright statement: originality is not easy, plagiarism and reprinting are prohibited in this article, and infringement must be investigated!
Table of contents
1. Karatsuba Tradition
When you do the multiplication of two numbers on paper, we generally use the method we learned when we were young: the
time complexity of this calculation method is O(n²), but is there any other way to speed up the calculation speed of the multiplication? ?
Karatsuba multiplication is a fast multiplication. This algorithm was proposed by Anatolii Alexeevitch Karatsuba in 1960 and published in 1962. This algorithm is mainly used for multiplying two large numbers. The time complexity of ordinary multiplication is O(n²), while the complexity of Karatsuba's algorithm is only O(3nlog2(3))
2. Algorithm idea
Notice that the calculation AD +BC requires two O(n²/4) multiplications and one O(n) addition.
(A+B)(C+D)-AC-BD = AC+AD+BC+BD-AC-BD = AD + BC
Karatsuba changed this original calculation to the above one since AC and BD are known , so now the time complexity of AD +BC becomes one O(n²/4) multiplication and four O(n) additions or subtractions, reaching the time complexity of O(n^log2(3))
3. Python algorithm implementation
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)
Output result:
As shown in the figure, the output result is correct
4. Author Info
Author: Xiaohong's fishing routine, Goal: Make programming more interesting!
Focus on algorithms, reptiles, game development, data analysis, natural language processing, AI, etc., looking forward to your attention, let us grow and code together!
Copyright Note: This article prohibits plagiarism and reprinting, and infringement must be investigated!