Karatsuba算法

Karatsuba算法是一种快速相乘算法,它由Anatolii Alexeevitch Karatsuba于1960年提出并于1962年发表。[1][2][3]它将两个位数字相乘所需的一位数乘法次数减少到了至多(如果是2的乘方,则正好为)。因此它比要次个位数乘法的经典算法要快。例如,对于两个1024位的数相乘(),Karatsuba算法需要次个位数乘法,而经典算法需要次。Toom–Cook算法是此算法更快速的泛型。对于充分大的,Schönhage–Strassen算法甚至更快,算法的时间复杂度为

值得一提的是,Karatsuba算法是第一个比小学二次乘法算法渐进快速的算法。

算法

基本步骤

Karatsuba的算法主要是用于两个大数的乘法,极大提高了运算效率,相较于普通乘法降低了复杂度,并在其中运用了递归的思想。基本的原理和做法是将位数很多的两个大数分成位数较少的数,每个数都是原来位数的一半。这样处理之后,简化为做三次乘法,并附带少量的加法操作和移位操作。

实现

伪代码实现

procedure karatsuba(num1, num2)
  if (num1 < 10) or (num2 < 10)
    return num1*num2
  /* calculates the size of the numbers */
  m = max(size_base10(num1), size_base10(num2))
  m2 = m/2
  /* split the digit sequences about the middle */
  high1, low1 = split_at(num1, m2)
  high2, low2 = split_at(num2, m2)
  /* 3 calls made to numbers approximately half the size */
  z0 = karatsuba(low1,low2)
  z1 = karatsuba((low1+high1),(low2+high2))
  z2 = karatsuba(high1,high2)
  return (z2*10^(2*m2))+((z1-z2-z0)*10^(m2))+(z0)

Python代码实现

# Python 2 and 3
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))
    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

参考文献

  1. A. Karatsuba and Yu. Ofman. . Proceedings of the USSR Academy of Sciences. 1962, 145: 293–294.
  2. A. A. Karatsuba. (PDF). Proceedings of the Steklov Institute of Mathematics. 1995, 211: 169–183 [2013-07-25]. (原始内容存档 (PDF)于2020-03-26).
  3. Knuth D.E.(1969)The art of computer programming. v.2. Addison-Wesley Publ.Co., 724 pp.
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.