首页 > 编程知识 正文

大整数的乘法分治法,实现大整数的乘法是利用的

时间:2023-05-05 15:10:19 阅读:240480 作者:88

目录 题目一种较为流行的思路(即分治)分析引入例子,便于理解源代码(附本人注释)程序流程图(Visio所画)测试用例(运行截图)总结(持续改进ing~~~)

题目

大整数乘法:用分治算法编程实现两个n位十进制大整数的乘法运算。

一种较为流行的思路(即分治)



分析 <大整数的乘法>在计算机中,长整形(long int)变量的范围不能超过10位数。即便用双精度(double)变量,也仅能保证16位有效数字的精度。在某些需要更高精度的乘法运算场合,需要用别的办法来实现运算。 比较容易想到的是做多位数乘法时列竖式进行计算的方法,只要写出模拟这一过程的程序,就能实现任意大整数的乘法运算。经过查阅资料,找到一种更易于编程的方法,即“列表法”。 引入例子,便于理解

在这里,我们令a=8765,令b=234即计算8765 X 234,(只是让我们便于理解,当然后面会涉及到“大数相乘”的例子)其中a又叫做“被乘数”,b又叫做“乘数”。
下面的几个表是本算法的精髓:(这几个表也是“列竖式”的方法的另一种形象表示)

附一张测试过程中的截图

可能有些不好理解,但是再加上几张我分析的图片,可以好理解一点:(1)

(2)

(3)

我认为其核心思想也就是乘数相加,储存乘数并且将其输出的过程。

源代码(附本人注释) #include<iostream>#include<string>using namespace std;int main(){ string a; //a,b分别可以参考8765 X 234, (结果2051010 为5位)下面按照这个来理解 string b; cout<<"请分别输入两个整数并回车:"; cout<<"n"; cin>>a>>b; int lena=a.size();//.size()用来返回字符串的长度,不包括'' int lenb=b.size(); int* tmp=new int[lena+lenb]; //a为被乘数,b为乘数 for(int y=0;y<lena+lenb;y++) { tmp[y]=0; //tmp[]数组用来储存a与b的每一位数互相乘后得的数,若a为m位,b为n位,则a与b相乘后的位数不超过m+n位 } int* C=new int[lena+lenb]; //保存最终相乘之后的每一位数,组合即为最终结果 <积> for(int i=0;i<lenb;i++) //数b的每一位数 如2,3,4 { for(int j=0;j<lena;j++) //数a的每一位数 如8,7,6,5 { //数字字符与对应十进制ASCII码之间差48,即数字0相当于ASCII码里的'48' //测试使用cout<<"tmp["<<j+i<<"]=";tmp[j+i]=tmp[j+i]+(int(b[i])-48)*(int(a[j])-48);//测试使用(理解)cout<<tmp[j+i]; cout<<"n"; //将每一个字符强制转换成整型的,再减去48,就是相对应的数字 } //对应表一。b的"最高位"依次与a的"从大到小位"相乘 ,比如得到初始的t[0]=16、t[1]=14、t[2]=12、t[3]=10 //保存在tmp【】里,在这里例如t[]每隔4个更新一下,分别3次存放相乘相加的结果,和“列竖式”一样 } int ii=0; for(int k=lena+lenb-2;k>=0;k--) { //用来计算最后的和,存放每一位数,放到C[]中,输出C[]时就是乘积 if(tmp[k]>=10 && k>=1) { tmp[k-1]=tmp[k-1]+tmp[k]/10; C[ii]=tmp[k]%10; ii++; } else if(tmp[k]<10 && k>=1) { C[ii]=tmp[k]; ii++; } else { if(tmp[0]>=10) { C[ii]=tmp[0]%10; ii++; C[ii]=tmp[0]/10; } else C[ii]=tmp[0]; } } cout<<"两数相乘的结果是:"; for(int h=ii;h>=0;h--) { cout<<C[h]<<""; } return 0;}

(上述代码中为了简便,我在注释里将tmp写成了t 哈!)

程序流程图(Visio所画)

测试用例(运行截图)

(1)

(2)8765 X 234

(2)999999999999999999999999 X
999999999999999999999999 (24个9 与 24个9相乘)

总结(持续改进ing~~~)

(1) 分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。
(2) 递归地解决这些子问题,然后将各个子问题的解合并得到原问题的解。
(3) 用分治法设计出的程序一般是递归算法,因此分治法的计算效率通常可以用递归方程来进行分析。
(4) 一个分治法经常将规模为n的问题分成k个规模为n/m的子问题去解

(对于是如何进行分治的,各位可以尽抒己见哈!)本题目用C++实现的方式可能不是太好理解(大佬请忽略),用java等语言应该会更加简便,各位可以加以补充建议!欢迎各位提意见喔!~~

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。