大整数乘法(Karatsuba算法)

📌 定义

大整数乘法是指计算两个位数很多的整数的乘积。传统的竖式乘法时间复杂度为O(n²),而Karatsuba算法通过分治思想将复杂度优化到O(n

示例:
1234 × 5678

传统方法: 需要16次乘法
Karatsuba: 只需要3次递归乘法

核心思路

将大整数拆分成两部分,使用分治法减少乘法次数:

对于两个n位数 x 和 y:
x = a × 10^(n/2) + b
y = c × 10^(n/2) + d

传统方法:
x × y = (a × 10^(n/2) + b) × (c × 10^(n/2) + d)
      = ac × 10^n + (ad + bc) × 10^(n/2) + bd
需要4次乘法: ac, ad, bc, bd

Karatsuba优化:
设:
z0 = ac
z1 = bd
z2 = (a + b)(c + d) - ac - bd = ad + bc

则: x × y = z0 × 10^n + z2 × 10^(n/2) + z1
只需3次乘法: ac, bd, (a+b)(c+d)

复杂度分析

方法时间复杂度空间复杂度说明
竖式乘法O(n²)O(1)传统方法
KaratsubaO(n^1.585)O(n)分治优化
Toom-CookO(n^1.465)O(n)更复杂的分治
FFTO(n log n)O(n)最快但实现复杂

其中 1.585 ≈ log₂(3)

Go 代码

Go 实现

package main
 
import (
    "fmt"
    "math"
)
 
func karatsuba(x, y int64) int64 {
    // 基准情况
    if x < 10 || y < 10 {
        return x * y
    }
 
    // 计算位数
    n := max(numDigits(x), numDigits(y))
    m := n / 2
    power := int64(math.Pow10(m))
 
    // 分割数字
    a, b := x/power, x%power
    c, d := y/power, y%power
 
    // 三次递归乘法
    z0 := karatsuba(a, c)
    z1 := karatsuba(b, d)
    z2 := karatsuba(a+b, c+d) - z0 - z1
 
    // 组合结果
    return z0*int64(math.Pow10(2*m)) + z2*int64(math.Pow10(m)) + z1
}
 
func numDigits(n int64) int {
    if n == 0 {
        return 1
    }
    count := 0
    for n > 0 {
        n /= 10
        count++
    }
    return count
}
 
func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}
 
func main() {
    var x, y int64 = 1234, 5678
    result := karatsuba(x, y)
    fmt.Printf("%d × %d = %d\n", x, y, result)
    fmt.Printf("验证: %d × %d = %d\n", x, y, x*y)
}

思路展开

递归树示例(1234 × 5678)

                    1234 × 5678
                    /     |     \
                   /      |      \
             12×56    (12+34)×(56+78)    34×78
              672         46×134         2652
             /  |  \      /  |  \       /  |  \
           1×5 (1+2)×(5+6) 2×6   ...   3×7 (3+4)×(7+8) 4×8

最终计算:
z0 = 672
z1 = 2652
z2 = 46×134 - 672 - 2652 = 6164 - 672 - 2652 = 2840

结果 = 672×10000 + 2840×100 + 2652
     = 6720000 + 284000 + 2652
     = 7006652

复杂度推导

T(n) = 递归求解n位数乘法的时间

传统方法:
T(n) = 4T(n/2) + O(n)
     = O(n²)

Karatsuba:
T(n) = 3T(n/2) + O(n)

根据主定理:
T(n) = aT(n/b) + f(n)
a = 3, b = 2, f(n) = O(n)

log_b(a) = log_2(3) ≈ 1.585

因为 f(n) = O(n) < O(n^1.585)
所以 T(n) = O(n^log_2(3)) = O(n^1.585)

经典题目

应用场景

  • 大整数计算库
  • 密码学运算
  • 科学计算
  • 高精度数值计算

相关算法

  • Toom-Cook算法(更高阶的分治)
  • Schönhage-Strassen算法(FFT based)
  • 大整数除法

⚖️ 优缺点

优点

  • ✅ 时间优化:O(n^1.585) vs O(n²)
  • ✅ 分治思想:经典的分治应用
  • ✅ 易于实现:相比FFT方法更简单

缺点

  • ❌ 常数因子大:小数字时不如直接乘法
  • ❌ 空间开销:递归需要O(n)空间
  • ❌ 实际应用:现代库通常使用FFT方法

🎨 应用场景

  1. 大整数库:Python的大整数运算内部使用
  2. 密码学:RSA等算法中的大数运算
  3. 科学计算:高精度数值计算
  4. 数学研究:数论问题求解

相关主题


返回:分治算法 | 算法学习导航