Python Algorithm Design - Karatsuba Multiplication

Copyright statement: originality is not easy, plagiarism and reprinting are prohibited in this article, and infringement must be investigated!

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

insert image description here

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:
insert image description here
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!

Guess you like

Origin blog.csdn.net/qq_44000141/article/details/130181020