综述:高精度算法即当需要操作的数过大时,通过模拟计算机加减乘除的步骤来得到结果。主要包括高精度加法,高精度减法,高精度乘法,高精度除法四种高精度算法。
首先是高精度算法的输入过程
string a,b; cin>>a>>b; vector<int> A,B; for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0'); for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0');
由于没有数据类型能够存储高精度数,所以需要借助字符串来输入,然后用vector来存储,把个位存在数组的首端,这样便于进行操作。
高精度加法:https://www.acwing.com/activity/content/problem/content/825/
AC代码如下:
#include<iostream> #include<vector> using namespace std; vector<int> add(vector<int> &A,vector<int> &B) { vector<int> C; int t=0;//t表示进位 for(int i=0;i<A.size()||i<B.size();i++) { if(i<A.size()) t+=A[i]; if(i<B.size()) t+=B[i]; C.push_back(t%10); t=t/10; } if(t) C.push_back(1);表示当A,B数组都操作完成后,t=1,说明应该进一位。 return C; } int main() { string a,b; cin>>a>>b; vector<int> A,B; for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0'); for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0'); auto C=add(A,B); for(int i=C.size()-1;i>=0;i--) cout<<C[i]; return 0; }
高精度减法:https://www.acwing.com/activity/content/problem/content/826/
AC代码如下:
#include<iostream> #include<vector> using namespace std; bool cmp(vector<int> &A,vector<int> &B)//判断A,B哪个数字更大 { if(A.size()>B.size()) return 1; if(B.size()>A.size()) return 0; if(A.size()==B.size()) { for(int i=A.size()-1;i>=0;i--) { if(A[i]>B[i]) return 1; if(B[i]>A[i]) return 0; } return 1; } } vector<int> sub(vector<int> &A,vector<int> &B) { vector<int> C; int t=0;//t表示进位 for(int i=0;i<A.size()||i<B.size();i++) { if(i<A.size()) t=A[i]-t; if(i<B.size()) t=t-B[i]; C.push_back((t+10)%10);//注意 if(t<0) t=1;//t<0说明需要向更高位借位,所以下一位计算时要减一 else t=0; } while(C.size()>1&&C.back()==0) C.pop_back(); return C; } int main() { string a,b; cin>>a>>b; vector<int> A,B; for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0'); for(int j=b.size()-1;j>=0;j--) B.push_back(b[j]-'0'); if(cmp(A,B)) { auto C=sub(A,B); for(int i=C.size()-1;i>=0;i--) cout<<C[i]; } else { auto C=sub(B,A); cout<<'-'; for(int i=C.size()-1;i>=0;i--) cout<<C[i]; } return 0; }
高精度乘法:https://www.acwing.com/activity/content/problem/content/827/
高精度乘法一般是一个高精度数乘以一个小于10w的数
AC代码如下:
#include<iostream> #include<vector> using namespace std; vector<int> mul(vector<int> &A,int b) { vector<int> C; int t=0; for(int i=0;i<A.size()||t!=0;i++)//注意循环的判断条件,如果A操作完而t!=0说明还需要进位 { if(i<A.size()) t=t+A[i]*b; C.push_back(t%10);//这里对t的操作与加法相同,可联系记忆。 t=t/10; } while(C.size()>1&&C.back()==0) C.pop_back();//去掉前置0 return C; } int main() { string a; int b; cin>>a>>b; vector<int> A; for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0'); auto C=mul(A,b); for(int i=C.size()-1;i>=0;i--) cout<<C[i]; return 0; }
高精度除法:https://www.acwing.com/activity/content/problem/content/828/
AC代码如下:
#include<iostream> #include<vector> #include<algorithm> using namespace std; vector<int> div(vector<int> &A,int b,int &t) { vector<int> C; t=0; for(int i=A.size()-1;i>=0;i--)//注意 { t=t*10+A[i]; C.push_back(t/b); t=t%b; } reverse(C.begin(),C.end());//注意 while(C.size()>1&&C.back()==0) C.pop_back(); return C; } int main() { string a; int b; cin>>a>>b; int t; vector<int> A; for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0'); auto C=div(A,b,t); for(int i=C.size()-1;i>=0;i--) cout<<C[i]; cout<<endl<<t; return 0; }
这样操作看上去有些复杂,但由于stl对vector只有去掉队尾元素无去掉队首元素的操作,所以高精度除法就显得有点麻烦。
高精度算法模拟的就是竖式计算,记忆模板并熟练使用即可。