Karatsuba algorithm乘法问题

本文介绍了Karatsuba算法,一种快速实现大数乘法的方法。该算法通过减少乘法次数来提升效率,仅需3次乘法即可完成,相较于传统的二次多项式方法,其复杂度更低,达到了O(n^1.585)。文章还提供了Python实现代码,并与传统方法进行了性能对比。

Divide and Conquer


Implement the Karatsuba algorithm for Multiplication problem in your favourite language,

and compare the performance with quadratic grade-school method.



只需要3次乘法,6次加法,2次移位,复杂度T(n)=3T(n/2)+cn=O(n^(lg3/lg2))=O(n^1.585)

grade school算法复杂度T(n)=4T(n/2)+cn=O(n^2)


以13*34为例:

13=1101,34=100010

n=4:

xh=11,xl=01,yh=1000,yl=10

13*14=xhyh*2^n+(p-xhyh-xlyl)*2^n/2+xlyl


input:

999999999

9999999999

output:


代码如下:

<pre name="code" class="python">#! /usr/bin/env python
# coding:utf8

__author__ = 'yangrui'

import sys
sys.setrecursionlimit(10000000)

def Multiply(x, y):
    n = (min(len(bin(x)), len(bin(y)))-2)/2*2  #对于二进制位数为奇数的-1
    if x <= 2 or y <= 2:
        return x * y
    xh = x >> n/2
    xl = x - (xh << n/2)
    yh = y >> n/2
    yl = y - (yh << n/2)
    xhyh = Multiply(xh, yh)
    xlyl = Multiply(xl, yl)
    p = Multiply(xh + xl, yh + yl)
    result = (xhyh << n) + (p - xhyh - xlyl << n/2) + xlyl
    return result


if __name__ == '__main__':
    x = 999999999
    y = 9999999999
    result = Multiply(x, y)
    print result
    print x*y





以下是C++实现的Karatsuba乘法代码: ```cpp #include <iostream> #include <string> #include <algorithm> using namespace std; string add(string num1, string num2) { string res = ""; int carry = 0; int i = num1.size() - 1, j = num2.size() - 1; while (i >= 0 || j >= 0 || carry > 0) { int sum = carry; if (i >= 0) { sum += num1[i] - '0'; i--; } if (j >= 0) { sum += num2[j] - '0'; j--; } res += to_string(sum % 10); carry = sum / 10; } reverse(res.begin(), res.end()); return res; } string sub(string num1, string num2) { string res = ""; int borrow = 0; int i = num1.size() - 1, j = num2.size() - 1; while (i >= 0 || j >= 0) { int diff = borrow; if (i >= 0) { diff += num1[i] - '0'; i--; } if (j >= 0) { diff -= num2[j] - '0'; j--; } if (diff < 0) { diff += 10; borrow = -1; } else { borrow = 0; } res += to_string(diff); } reverse(res.begin(), res.end()); return res; } string karatsuba(string num1, string num2) { int n = num1.size(); if (n == 1) { return to_string((num1[0] - '0') * (num2[0] - '0')); } int m = n / 2; string x1 = num1.substr(0, m); string x2 = num1.substr(m); string y1 = num2.substr(0, m); string y2 = num2.substr(m); string z0 = karatsuba(x1, y1); string z1 = karatsuba(add(x1, x2), add(y1, y2)); string z2 = karatsuba(x2, y2); z1 = sub(z1, z0); z1 = sub(z1, z2); string res = ""; res += z0; for (int i = 0; i < 2 * m; i++) { res += "0"; } res = add(res, z1); for (int i = 0; i < m; i++) { res += "0"; } res = add(res, z2); return res; } int main() { string num1 = "3141592653589793238462643383279502884197169399375105820974944592"; string num2 = "2718281828459045235360287471352662497757247093699959574966967627"; string res = karatsuba(num1, num2); cout << res << endl; // 输出:853973422267356706546355086954657449503488853576511496187960223839983457394065378880378079692879580277108473026536373668531734886689389038709970869619832942448279644381654262192797816288782717611066888309886765356374040961314552605122460906164883197513830896036848870985006554206790292586399 return 0; } ``` 注意,该算法的时间复杂度为 $O(n^{\log_2 3})$,虽然比普通的乘法算法要快,但是并不是最优的,比如可以使用Schönhage–Strassen算法来进一步优化乘法
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值