我们平时接触的长乘法,按位相乘,是一种时间复杂度为 O(n ^ 2) 的算法。今天,我们来介绍一种时间复杂度为 O (n ^ log 3) 的大整数乘法(log 表示以 2 为底的对数)。

介绍原理

karatsuba 算法要求乘数与被乘数要满足以下几个条件,第一,乘数与被乘数的位数相同;第二,乘数与被乘数的位数应为 2 次幂,即为 2 ^ 2, 2 ^ 3, 2 ^ 4, 2 ^ n 等数值。

下面我们先来看几个简单的例子,并以此来了解 karatsuba 算法的使用方法。

两位数相乘

我们设被乘数 A = 85,乘数 B = 41。下面来看我们的操作步骤:

将 A, B 一分为二,令 p = A 的前半部分 = 8,q = A 的后半部分 = 5 , r = B 的前半部分 = 4 ,s = B 的后半部分 = 1,n = 2。通过简单的数学运算:

A * B = pq * rs = (p * 10 + q) * (r * 10 + s) = p * r * 10 ^ 2 + (p * s + q * r ) * 10 + q * s。

令 u = p * r,v =(p - q) * (s - r),w = q * s。所以 A * B = u * 10 ^ 2 + (u + v + w) * 10 + w。

换成数值求解的过程如下:

A * B = 85 * 41 = (8 * 10 + 5) * ( 4 * 10 + 1) = 8 * 4 * 10 * 10 + (8 * 1 + 5 * 4) * 10 + 5 * 1。

其中 u = 8 * 4 = 32,v = (8 - 5) (1 - 4) = -9,w = 5 * 1 = 5。

所以,A * B = 32 * 100 + (32 - 9 + 5) * 10 + 5 = 3485。与长乘法所得结果一致。

四位数相乘

我们设被乘数 A = 8537,乘数 B = 4123。下面来看我们的操作步骤:

将 A, B 一分为二,令 p = A 的前半部分 = 85,q = A 的后半部分 = 37 , r = B 的前半部分 = 41 ,s = B 的后半部分 = 23,n = 4。

==> 其中,u = 85 * 41, v = (85 - 37) * (23 - 41), w = 37 * 23。

==> A * B = 8537 * 4123 = u * 10 ^ 4 + (u + v + w) * 10 ^ 2 + w = 3485_0000 +34_7200 + 851 = 35198051。

在我们计算 u, v, w 的过程中又会涉及两位数的乘法,我们继续使用 Karatsuba 算法得出两位数相乘的结果。

N 位数相乘

我们令 n 为 乘数与被乘数的位数,令 p = A 的前半部分,q = A 的后半部分, r = B 的前半部分 ,s = B 的后半部分。

==> 其中, u = p * r,v = (p - q) * (s - r),w = q * s。

所以 A * B = u * 10 ^ n + (u + v + w) * 10 ^ (n / 2) + w。

而 u, v, w 则是两个 n / 2 位的乘法运算。我们继续调用 Karatsuba 算法计算 u, v, w 的数值。接着,我们在计算 n / 2 乘法的过程中又会遇到 n / 4 位的乘法运算……以此类推,直到我们遇到两个个位数的乘法,我们就直接返回这两个个位数乘法的结果。层层返回,最终得到 N 位数的乘法结果。

时间复杂度

我们平常使用的长乘法,是 O (n ^ 2) 的时间复杂度。比如两个 N 位数相乘,我们需要将每一位按规则相乘,所以需要计算 N * N 次乘法。而使用 Karatsuba 算法每层需要计算三次乘法,两次加法,以及若干次加法,每使用一次 karatsuba 算法,乘法规模就下降一半。

所以,对于两个 n = 2 ^ K 位数乘法运算,我们需要计算 3 ^ k 次乘法运算。而 K = log n(底数为 2), 3 ^ K = 3 ^ log n = 2 ^ (log 3 * log n) = 2 ^ (log n * log 3) = n ^ log 3 (底数为 2)。

代码实现

from math import log2, ceil

def pad(string: str, real_len: int, max_len: int) -> str:

pad_len: int = max_len - real_len

return f"{'0' * pad_len}{string}"

def kara(n1: int, n2: int) -> int:

if n1 < 10 or n2 < 10:

return n1 * n2

n1_str: str = str(n1)

n2_str: str = str(n2)

n1_len: int = len(n1_str)

n2_len: int = len(n2_str)

real_len: int = max(n1_len, n2_len)

max_len: int = 2 ** ceil(log2(real_len))

mid_len: int = max_len >> 1

n1_pad: str = pad(n1_str, n1_len, max_len)

n2_pad: str = pad(n2_str, n2_len, max_len)

p: int = int(n1_pad[:mid_len])

q: int = int(n1_pad[mid_len:])

r: int = int(n2_pad[:mid_len])

s: int = int(n2_pad[mid_len:])

u: int = kara(p, r)

v: int = kara(q-p, r-s)

w: int = kara(q, s)

return u * 10 ** max_len + (u+v+w) * 10 ** mid_len + w

输出结果:

==> kara(123456, 9734) == 123456 * 9734

==> kara(1234233456756, 32459734) == 1234233456756 * 32459734

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

python两数相乘代码_Python 实现大整数乘法算法的示例代码相关推荐

  1. python如何计算超大整数_Python 实现大整数乘法算法

    介绍原理 karatsuba 算法要求乘数与被乘数要满足以下几个条件,第一,乘数与被乘数的位数相同:第二,乘数与被乘数的位数应为  2 次幂,即为 2 ^ 2,  2 ^ 3, 2 ^ 4, 2 ^ ...

  2. 分治法实验之大整数乘法(算法设计分析)

    分治法实验之大整数乘法 01. 问题描述 02. 输入格式 03. 输出格式 04. 输入样例 05. 输出样例 06. 问题分析 07. 算法设计 08. 代码实现 09. 测试结果 10. 复杂度 ...

  3. python简单目标检测代码_Python Opencv实现单目标检测的示例代码

    一 简介 目标检测即为在图像中找到自己感兴趣的部分,将其分割出来进行下一步操作,可避免背景的干扰.以下介绍几种基于opencv的单目标检测算法,算法总体思想先尽量将目标区域的像素值全置为1,背景区域全 ...

  4. python调用程序压缩文件_Python实现文件压缩和解压的示例代码

    大家可能都熟悉.zip格式的文件.它可以把多个文件,压缩成一个文件.这在网络上传输时很有用,而且节省硬盘空间. 接下来,我们使用Python实现压缩和解压. 读取ZIP文件信息 要读取ZIP文件的内容 ...

  5. python修改自己的代码_python修改微信和支付宝步数的示例代码

    项目意义 如果你想在支付宝蚂蚁森林收集很多能量种树,为环境绿化出一份力量,又或者是想每天称霸微信运动排行榜装逼,却不想出门走路,那么该python脚本可以帮你实现. 实现方法 手机安装第三方软件乐心健 ...

  6. python人像动漫化_python实现人像动漫化的示例代码

    利用百度api实现人像动漫化 百度API地址:https://ai.baidu.com/tech/imageprocess/selfie_anime 技术文档:https://ai.baidu.com ...

  7. python两数相乘怎么表示_python 用加法实现a,b两数相乘

    """ 思路:1.a * b = a + a + a + - 2.a * b = n个a相加,只需求证b = n即可 3.用for 循环遍历即可,b就是range的最大次 ...

  8. python两数交换 函数_Python 为什么只需一条语句“a,b=b,a”,就能直接交换两个变量?...

    从接触 Python 时起,我就觉得 Python 的元组解包(unpacking)挺有意思,非常简洁好用. 最显而易见的例子就是多重赋值,即在一条语句中同时给多个变量赋值: >>> ...

  9. python两数交换 函数_python 函数(二)

    [toc] python 函数(二) nolocal 关键字使用了nolocal关键字,将变量标记为在上级的局部作用域中的定义,但不能是全局作用域中定义 count 是外层函数的局部变量,被内部函数引 ...

最新文章

  1. 在“内卷”、“红海”的2020 年,开垦计算机视觉领域的知识荒原:BatchNorm
  2. 零基础如何学好数据分析?
  3. 吉林财经计算机学院怎么样,2019年9月吉林财经大学计算机等级考试报名通知
  4. cubemx lan8720模块_通过STM32cubeMX将STM32F767+LAN8720+LwIP+FreeRTOS的以太网实现
  5. lambda显式声明返回值
  6. 计蒜客 《程序设计竞赛体验课程》第一部分 快速提升代码能力
  7. python3.5 连接mysql_python3.5 連接mysql本地數據庫
  8. 建设工程项目全寿命周期管理是指_(必过)2020年二建机电《施工管理》考前必背精华知识点整理一...
  9. xjad java反编译工具使用
  10. 计算机机房需要装排烟风机不,送风机房和排烟机房的作用分别是什么
  11. 说说财务系统中的月末结账功能
  12. HotPower超级CRC计算器与第三方CRC计算器名词解释与对照及操作
  13. 说说DBA职责和目标
  14. 常用moment时间总结
  15. 《LoadRunner虚拟用户开发指南》写作心语
  16. Elasticsearch 中为什么选择倒排索引而不选择 B 树索引
  17. 2011大纽约区域赛试题 Decoding EDSAC Data 解题报告
  18. NBA GLOSSARY
  19. Python | 实现简单的康威生命游戏
  20. 红外热成像仪原理与用途——TFN TD97 双目手持热像仪红外夜视仪

热门文章

  1. 最完整的MySQL规范
  2. Apache Log4j2远程代码执行漏洞攻击,华为云安全支持检测拦截
  3. 带你认识9种常用卷积神经网络
  4. 华为云原生数据仓库GaussDB(DWS)深度技术解读:融、快、大、稳、易
  5. 通过python基于netconf协议获取网络中网元的配置数据,助力企业网络控制自动化轻松实现!
  6. 原来AI也可以如此简单!教你从0到1开发开源知识问答机器人
  7. 【华为云技术分享】选择困难症必看!云服务器操作系统选择技巧+经验
  8. 14岁AI天才的钢铁之心
  9. vrm华为_华为-笔记本电脑如何安装FusionCompute虚拟化平台?
  10. 长庆企业信息化管理课件_会博通浅谈企业档案管理信息化的必要性和优势