Python-Algorithmus-Design – Karatsuba-Multiplikation

Urheberrechtserklärung: Originalität ist nicht einfach, Plagiate und Nachdruck sind in diesem Artikel verboten und Verstöße müssen untersucht werden!

1. Karatsuba-Tradition

Wenn Sie die Multiplikation zweier Zahlen auf Papier durchführen, verwenden wir im Allgemeinen die Methode, die wir in jungen Jahren gelernt haben: Die

Fügen Sie hier eine Bildbeschreibung ein

zeitliche Komplexität dieser Berechnungsmethode beträgt O(n²), aber gibt es eine andere Möglichkeit, die Berechnungsgeschwindigkeit zu beschleunigen? Multiplikation? ?

Die Karatsuba-Multiplikation ist eine schnelle Multiplikation. Dieser Algorithmus wurde 1960 von Anatolii Alexeevitch Karatsuba vorgeschlagen und 1962 veröffentlicht. Dieser Algorithmus wird hauptsächlich zum Multiplizieren zweier großer Zahlen verwendet. Die Zeitkomplexität der gewöhnlichen Multiplikation beträgt O(n²), während die Komplexität des Karatsuba-Algorithmus nur O(3nlog2(3)) beträgt.

2. Algorithmusidee

Beachten Sie, dass die Berechnung AD +BC zwei O(n²/4)-Multiplikationen und eine O(n)-Addition erfordert.

(A+B)(C+D)-AC-BD = AC+AD+BC+BD-AC-BD = AD + BC

Karatsuba änderte diese ursprüngliche Berechnung in die obige, da AC und BD bekannt sind, also jetzt die Zeit Die Komplexität von AD + BC wird zu einer O(n²/4)-Multiplikation und vier O(n)-Additionen oder -Subtraktionen, wodurch die Zeitkomplexität von O(n^log2(3)) erreicht wird.

3. Implementierung des Python-Algorithmus

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)

Ausgabeergebnis:
Fügen Sie hier eine Bildbeschreibung ein
Wie in der Abbildung gezeigt, ist das Ausgabeergebnis korrekt

4. Autoreninformationen

Autor: Xiaohongs Angelroutine, Ziel: Programmieren interessanter machen!

Konzentrieren Sie sich auf Algorithmen, Reptilien, Spieleentwicklung, Datenanalyse, Verarbeitung natürlicher Sprache, KI usw. und freuen Sie sich auf Ihre Aufmerksamkeit. Lassen Sie uns gemeinsam wachsen und programmieren!

Urheberrechtshinweis: Dieser Artikel verbietet Plagiate und Nachdrucke und Verstöße müssen untersucht werden!

Acho que você gosta

Origin blog.csdn.net/qq_44000141/article/details/130181020
Recomendado
Clasificación