大整数乘法的数据结构及算法选择探究
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
为了使处理方法更加行之有效 , 经过大量实践发
现 , 最好使 k 个子问题的规模大致相同 。分治法
通常由递归程序实现 ,所以 ,将一个规模为 n 的问
题分解为 k 个规模为 ( n/ m) 的子问题 , 然后求解
各个子问题 , 再将各个子问题的解合并 , 经求解
得:
logm n - 1
∑ T ( n) = N logm K +
般情况保存相乘的结果已经足够 。
1. 2 大整数乘法的算法选择与分析
大整数乘法中由于要使用字符数组来存储各
个数位 ,进行乘法过程中的转换 、移位 、相乘 、相加
的效率很低 ,理想算法的选择往往是提高效率的
关键 。通常的算法都是采用和日常计算乘法相同
的算法 ,即相乘移位相加的方法 。这样 ,如上所设
Data structure and algorithm selection of big integer multiplication
YIN G Chang2sheng1 , ZHOU Xi2lo ng2
(1. College of Comp uter , Jilin Normal Universit y , Siping 136000 , China ; 2. School of Co mp uter Science & Engineering , Changchun Universit y of Technology , Changchun 130012 , China)
205
4 个字节共 32 位 , 保存数值的范围最大可达到 232 - 1 ,但是在运算时 , 涉及到乘法 、进位 、移位等 操作 ,算法复杂 ,效率低下 。而且 C # [5] 语言是托 管的安全语言 ,不能进行相对低级的位操作 。所 以采用整型数组不适合 。这里选取用字符数组来 存储结果的各个数位 ,每个数组元素占用一个字 节 ,存储结果的一个数位 ,这样既可以节省存储空 间 ,又便于程序对各个数位进行处理 (数字和其对 应字符的 A SCII 码只相差 32) 。在 C # 中 ,St ring 类是一个功能非常强大的类 ,它拥有许多有效的 属性和方法 。但是 St ring 类实际上是一个不可 变的数据类型 ,一旦对字符串对象进行了初始化 , 该字符串对象就不能改变了 。修改字符串内容的 方法和运算符 ,实际上是创建一个新的字符串 ,如 果必要 ,可以把旧字符串的内容复制到新字符串 中 。对于字符数组的处理是按只读来进行的 ,如 果对数组内容进行频繁的修改 、删除 ,效率会很 低 ,造成大量空间的浪费 ,甚至系统崩溃 。例如 , 下面的代码 :
X 为 m 位 , Y 为 n 位 , 则计算 X 3 Y 的时间复杂
度就为 O ( m 3 n) 。所以 , 采用分治法[6] 来提高效
率 。分治法的基本思想是将一个规模为 n来自百度文库的问题
分解为 k 个规模较小的子问题 , 这些子问题相互
独立且与原问题相同 。递归求解各个子问题 , 然
后合并各个子问题的解 , 从而得到原问题的解。
需要重新分配内存 。对字符串的修改就在赋予
St ringBuilder 对象的存储单元中进行 ,这就大大
提高了添加子字符串和替换单个字符的效率 。该
类提供了处理字符数组的大部分功能 ,而且对
St ringBuilder 类型的变量来说 ,它的理论上限是
Int32. MaxValue 个字符 (即 232 - 1 个) ,对于一
内存会比需要的更多 。开发人员可以选择显示指
定 St ringBuilder 要分配多少内存 ,但如果没有显
示指定 ,存储单元量在默认情况下就根据 St ring2
Builder 初 始 化 时 的 字 符 串 长 度 来 确 定 。为
St ringBuilder 设置初始容量时 ,最好把容量设置
为字符串可能的最大长度 ,确保 St ringBuilder 不
midOne < = len ( PartOne) / 2 ; mid Two < = len ( Part Two) / 2 ;
第 29 卷第 2 期 长 春 工 业 大 学 学 报 (自然科学版) Vol1 29 ,No . 2 2008 年 4 月 Jo urnal of Changchun U niversity of Technology (Nat ural Science Edition) Ap r1 2008
Abstract : Wit h C language , t he big integer multiplicatio n is realized based o n divisio n met hod. The algorit hm is efficient , simple and feasible. Key words : big integer ; divisio n ; data st ruct ure.
收稿日期 : 2008203206 作者简介 : 英昌盛 (1979 - ) ,男 ,汉族 ,山东费县人 ,吉林师范大学助教 ,长春理工大学硕士研究生 ,主要从事图像处理方向研究 , E2
mail :laoying79 @163. com.
第 2 期 英昌盛 , 等 : 大整数乘法的数据结构及算法选择探究
大整数乘法的数据结构及算法选择探究
英昌盛1 , 周喜龙2
(1. 吉林师范大学 计算机学院 , 吉林 四平 136000 ; 2. 长春工业大学 计算机科学与工程学院 , 吉林 长春 130012)
摘 要 : 采用 C # 语言基于分治法实现大整数相乘 ,提高了效率 ,并使算法更清晰易懂 ,在应 用上有重要价值 。 关键词 : 大整数 ; 分治法 ; 数据结构 中图分类号 : TP301. 6 文献标识码 : A 文章编号 : 167421374 (2008) 0220204204
206
长 春 工 业 大 学 学 报 (自然科学版) 第 29 卷
处理也相同) ;将 Y 分解为 C , D 。 则 X 3 Y = (A 3 10^ceiling ( m/ 2) + B) 3 ( C 3 10^ceiling ( n/ 2) + D) = A 3 C 3 10^ceiling ( m/ 2) 3 10^ceiling ( n/ 2) + A 3 D 3 10^ceiling ( m/ 2) + B 3 C 3 10^ceiling (n/ 2) + B 3 D 。 对于 A 3 C ,A 3 D ,B 3 C ,B 3 D ,也用递归方 式进行分解 ,直至 4 个子式的分解子式中的两部 分中的 1 个位数为 1 时 ,就可以对该子式进行运 算 ,否则继续分解 。然后 ,将所有子式分解后相乘 的结果进行累加 ,得到 4 个子式的值 ,最终累加得 到 X 3 Y 的结果 。 接下来创建 1 个专门用于对上面分解完成的 St ringBuilder 对象进行处理的 St ringProcess. cs 。 该类的主要功能就是完成对 2 个大整数的分解 , 相乘和 累 加 。在 类 中 首 先 完 成 对 2 个 给 定 的 St ringBuilder 串的数位对准并相加 ,因为要从最 低的数位开始相加 ,而且在相加的过程中可能产 生进位 ,所以 ,在生成 St ringBuilder 串时 ,采用倒 序方法生成 ,第 0 位保存的是最低数位 ,即所有新 添加的数位都存放在当前 St ringBuilder 对象的 末尾 。然后 ,实现两个 St ringBuilder 串所代表的 大整数相乘 ,再实现大整数的分治法分解 。关键 代码如下 :
1 大整数乘法数据结构 、算法选择与分析
很多研究人员都提出并实现了相关的大整数 乘法 ,但在效率和精度方面都有一定限制 。有的 采用整型数组实现 ,但实现算法过于复杂 ,不利于 其它领域的推广应用[1] ;有的考虑系统的硬件支
持和限制[2] ;有的实现语言本身有效率方面的限 制[3] ;还有的采用数据结构不合理 , 导致效率较 低[4] 。 1. 1 大整数乘法的数据结构选择与分析 设大整数 X 为 m 位 , Y 有 n 位 ,将 X 和 Y 的 各个数位拆分 , 这样 X 3 Y 的结果的位数也不会 超过 m + n 位 , 所需存储的位数的最大值为 2 3 ( m + n) + 1 (其中多出的 1 位是辅助位) 。由于 m 和 n 不固定 ,所以 ,存储结构不能用静态数组来实 现 ,尤其在多个大整数相乘时 ,保存相乘结果只能 从堆中临时分配 。如果采用整型数组来存储各个 数位 ,设每个数组元素只存放一个数位 , 而在 C # 中每个整型数占 4 个字节 , 这样存储空间是上面 计算的数值的 4 倍 ,浪费比较严重 ;若每一个数组 元素存放多个数位 ,例如 ,每个数组元素所占用的
kj f
j =0
n mj
在分解到原子规模时 , 就采取类似原码移位
乘的方法 , 即将各数位相乘 , 然后移位相加 , 并在
此过程中处理进位问题 。
2 实现与效率
2. 1 实现过程 在实现过程中 , 采用 10 为基[7] 。首先 , 将两 个待乘的大整数中位数较大的一个用 X 表示 , 另 一个用 Y 表示 ,然后 , 将 X 分解为 A , B (其中 , A 为 X 中数位的左半部分 , B 为右半部分 , 左半部 分的位数大于等于右半部分位数 , 下面对于 Y 的
void MultiBigInteger (St ringBuilder PartOne , St ringBuild2 er Part Two ,St ringBuilder Result)
{ / / 求出两个串的中间位置 ,并求出 A ,B ,C ,D 的长度 。这 里我们要求串左到右 ,从低向高排列/ / AB 3 CD = > BA 3 DC。
0 引 言
大整数在密码学 、生物信息 、基因工程等多个 领域都有重要的应用价值 。大整数无法在程序设 计语言能直接表示的整数范围内进行表示和处 理 ,用浮点数只能近似表示其大小 ,而且有效数字 位数也受到影响 。为了能精确表示大整数 ,得到 计算结果中所有数位上的精确数值 ,并提高计算 的效率 ,必须选择合适的数据结构和有效的算法 。
st ring greeting Text = " Hello World !" ; greeting Text + = "
You enjoy it . " ;
在执行这段代码时 ,首先 ,创建一个 System. St ring 类型的对象 ,并将之初始化为文本“Hello World !”。此时. N E T 运行库会为该字符串分配 足够的内存来保存这个文本 ,再设置变量 greet2 ing Text ,表示这个字符串对象 。从语法上看 ,下 一行代码是把更多的文本添加到字符串中 。实际 上并非如此 ,系统创建一个新字符串对象 ,给它分 配足够的内存 ,以保存合并之后的文本 。将最初 的文本“Hello World !”先复制到这个新字符串 中 ,再将第二行中的文本“Yo u enjoy it . ”添加到 其末尾 ,然后更新存储在变量 greeting Text 中的 地址 ,使变量正确地指向新的字符串对象 。旧的 字符串对象被撤销了 ,不再有变量引用它 ,下一次 垃圾收集器清理应用程序中所有未使用的对象 时 ,就会将其删除 。不使用的变量所占用的存储 空间直到垃圾收集器执行清理时才释放 ,. Net 垃 圾收集器何时进行清理 ,由. Net CL R 根据需要决 定 ,而不是由程序开发人员决定 。若程序中有大 量的字符串运算 ,则空间浪费现象会十分严重 。 而 在 C # 中 提 供 另 外 一 种 处 理 字 符 的 类 St ringBuilder ,它的工作方式非常高效 。在使用 St ring 类构造一个字符串时 ,要给它分配足够的 内存来保存字符串 ,但 St ringBuilder 通常分配的