算法--大数乘法
??????????? 常用的大数相乘算法有模拟加减法和分治法,第一种符合我们的运算习惯,第二种用数学方法提高了效率,(具体描述与实现可参考http://www.cnblogs.com/heyonggang/p/3599857.html)而两种各有优势的方法的程序实现都比较复杂,并且不易于初学者理解,于是我琢磨出了一个将它们合二为一的方法,将权值与数组下标对应,而且其原理通俗易懂,所编程序也较简单。 ?????? 首先,通过一个例子来展示我们所运用的运算规律: 12*45=540; 12=1*10^1+2*10^0;------------------------把12每一位分解开 45=4*10^1+5*10^0;------------------------把45每一位分解开 12*45=(1*10^1+2*10^0)*(4*10^1+5*10^0)--------多项式相乘 ???????????? =1*4*10^(1+1)+1*5*10^(1+0)--------------可知n位数乘m位数需进行n*m次乘法 ??????????????????????????????????? +2*4*10^(0+1)+2*5*10^(0+0)-----和(n-1)*(m-1)次加法 ???????????? =4*10^2????????? +13*10^1??????? +10*10^0-------每一项其指数都是原来相乘的项 ????????????????????????????????????????????????????????????????????????? --------的指数和?????????????? ???????????? =540----------------而且积的位数为n+m(最高位有进位)或n+m-1(最高位无进位); 观察上面算式得出算法: 输入两个大数,并且将它们逆序保存在数组a与b中: ? 大数a[n]={a[0],a[1],...,a[n]},大数b[m]={b[0],b[1],b[2],b[m]}; ? 声明保存结果的数组c[n+m];并且将元素初始化全为0; 其中,每一位的指数即是其下标,而分解相乘后的每一项值与指数分别为a[i]*b[j]和i+j; 将a[i]*b[j]保存在c中以i+j为下标的的位置,仍然以上例来做演示,到这一步时c中元素为
下面贴上c/c++代码:
#include<cstdio> #include<cstring> #include<iostream> #include<sstream> #include <cstdlib> using namespace std; void assignment(int* s,int n){ for(int i=0;i<n;i++){ s[i]=0; } } void Multiplication(char *arr1,char* arr2,int* Result){ int n,m;n=strlen(arr1);m=strlen(arr2); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ Result[i+j]=Result[i+j]+(arr1[i]-'0')*(arr2[j]-'0'); } } } void reorganize(int *Result,int n){ int t; for(int i=0;i<n;i++){ if(Result[i]>9){ t=Result[i]%10; Result[i+1]=Result[i+1]+Result[i]/10; Result[i]=t; } } } int main(){ string s1,s2; int n,m;char h; cin>>s1>>s2; n=s1.length();m=s2.length(); char *arr1=new char[n];char *arr2=new char[m]; int *Result=new int[n+m]; assignment(Result,n+m); int i=0,j=0; stringstream ss1(s1);while(ss1>>h)arr1[i++]=h;arr1[i]=' '; stringstream ss2(s2);while(ss2>>h)arr2[j++]=h;arr2[j]=' '; arr1=strrev(arr1);arr2=strrev(arr2); Multiplication(arr1,arr2,Result); reorganize(Result,n+m); int k,z=0;k=n+m; while(k--){ if(Result[0]!=0||Result[k+1]==0&&Result[k]!=0){ z=1; } if(z==1)printf("%d",Result[k]); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |