【数据结构】大数相乘 块链串
输出两个不超过100位的大整数的乘积。
【样例输入】
1234567891011121314151617181920
2019181716151413121110987654321
【样例输出】
2492816912877266687794240983772975935013386905490061131076320
#include<bits/stdc++.h> using namespace std; #define Maxsize 1101 int main() { int intnum1[Maxsize],intnum2[Maxsize]; int n1=0,n2=0; cin>>intnum1>>intnum2; int *result=new int[n1+n2];// 分配一个空间,用来存储运算的结果,num1长的数 * num2长的数,结果不会超过num1+num2长 memset(result,0,sizeof(int)*(n1+n2)); // 9 8 // × 2 1 //------------- // (9)(8) <---- 第1趟: 98×1的每一位结果 // (18)(16) <---- 第2趟: 98×2的每一位结果 //------------- // (18)(25)(8) <---- 这里就是相对位的和,还没有累加进位 //--------------------- int i=0,j=0; for(i=0;i<n1;i++) // 先不考虑进位问题,根据竖式的乘法运算,num1的第i位与num2的第j位相乘,结果应该存放在结果的第i+j位上 { for(j=0;j<n2;j++) { result[i+j+1]+=intnum1[i]*intnum2[j];//注意在此时+=,9+16在同一下标操作(因为进位的问题,最终放置到第i+j+1位) }//空出了result[0]的位置 看嘛i=j=0的时候直接result[1]了 } i--;j--;//!!!一定要记得i--,j--;实际的i和j最后出循环多加了1 for(int k=i+j+1;k>0;k--)//单独处理进位,从个位处理的数开始,即最后的下标 { if(result[k]>=10&&result[k]<100)//进位为10了 { result[k-1]+=result[k]/10;//注意是+= result[k]%=10; } } for(int m=0;m<=i+j+1;m++) { if(result[0]==0) continue; else cout<<result[m]; } }
用块链串知识: 块链串: 本质依然是顺序存储,每个字串用数组接纳,各内存块用指针顺序链接
比如每一个结点存储5位,12345678983426801则需要4个结点;先实现大整数乘上一个一位数;再实现两个大数相加。
用这样的链式存储形式便于计算:12--->34567--->89834--->26801 或者:26801--->89834--->34567--->12
来自于组里的大神:
#include<bits/stdc++.h> using namespace std; int result[210]; //块链串 struct Link { int maxsize; int num[5]; Link *next; }; //初始化块链串 Link *Init(Link *p,char s[]) { Link *head = p; for(int i=0; s[i]!='\0'; i++) { if(i!=0&&i%5==0)//用过一轮,数组满了,需要重新分配空间 { p->next = new Link(); p = p->next; } p->num[i%5]=s[i]-'0'; p->maxsize = i%5; } p->next=NULL; return head; } //核心算法 void bigNum(Link *head1,Link *head2) { Link *p,*q; //M,N是偏移值 //M处理第一个串的不同节点之间的相加时的定位 //N处理另一个串 int N=0,M=0; int i=0,j; //max是当前最大长度。 int max=0; //乘法部分: //从第一个串的头部开始遍历。 for(p=head1; p!=NULL; p=p->next) { //如果第一个串一个结点存不下所有的值,那么就涉及到不同结点之间,相加乘积时的定位问题 if(p!=head1) N+=5; //遍历第一个串的具体结点 for(i=0; i<=p->maxsize; i++) { for(q=head2; q!=NULL; q=q->next) { if(q!=head2) M+=5; for(j=0; j<=q->maxsize; j++) { //因为涉及到进位问题,所以+1预留一个进位空间。 //M+N+i+j+1即是目前需要相加的偏移量。 result[M+N+i+j+1]+=q->num[j]*p->num[i]; //cout<<i<<" "<<j<<" "<<i+j+N+M+1<<endl; //得到最大长度,便于确定result结果数组的长度。 max=max>M+N+1+j+i?max:M+N+i+j+1; } } //M和N的区别,M需要重新置为0 M=0; } } /*for(int k=0; k<=max; k++) cout<<result[k]<<" "; cout<<endl;*/ //处理进位: for(int k=max;k>0; k--) { if(result[k]>=10) { result[k-1]+=result[k]/10; result[k]%=10; } } //如果结果没有多一位,第一位则是0,输出时就要跳过 //如果进位,就直接输出。 int k=0; if(result[k]==0) k++; for(; k<=max; k++) cout<<result[k]; cout<<endl; } int main() { //freopen("in.txt","r",stdin); char s[100],t[100]; cin>>s>>t; Link *head1,*head2,*p; p = new Link(); head1 = Init(p,s); p = new Link(); head2 = Init(p,t); bigNum(head1,head2); return 0; } © 2019 GitHub, Inc.