一、高精度加法
1、思路
高精度加法一般都是由于所需要加的数字位数过大,如1e6位,想要实现,我们需要开数组来存储每一位,然后依次对每一位相加,同时进行进位,具体看代码展示
逆序输入是为了方便进位
2、代码
#include<iostream>
#include<vector>
using namespace std;
const int N=1e6+10;
vector<int> add(vector<int> &A,vector<int> &B)
{
vector<int> C;
int t=0;//用来计算每一位加完后的数字
for(int i=0;i<A.size()||i<B.size();i++)//当A,B中较长的所有位遍历完再结束,
{
if(i<A.size())//当这一位上A有数字时,t加上这个数
t+=A[i];
if(i<B.size())//当这一位上B有数字时,t加上这个数
t+=B[i];
C.push_back(t%10);//将所得结果的各位输到C中
t/=10;//t保留进位数字给下一位加上
}
if(t)//最后的一位要是仍有进位,就在最后加个1
C.push_back(1);
return C;
}
int main()
{
string a,b
vector<int> A,B,C;
cin>>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');
C=add(A,B);
for(int i=C.size()-1;i>=0;i--)
printf("%d",C[i]);
return 0;
}
二、高精度减法
1、思路
与加法相差不多,需要注意2点
1、我们需要先判断被减数和减数的大小,让绝对值大的减绝对值小的
2、我们用t当前位的数,同时也表示是否借位,每次遍历到新的一位时,都先减去t,然后用t+A[i]-B[i],存当前位计算完的值。
(t+10)%10,当不需要借位时,计算完t肯定是个大于等于0的个位数,%10取的是个位数,所以+10不影响。当需要借位时,t肯定是个负数,借位+10后就是所得结果
2、代码
#include<iostream>
#include<vector>
using namespace std;
bool cmp(vector<int> &A,vector<int> &B)//判断两个数字谁大谁小
{
if(A.size()!=B.size())//如果A,B位数不同
return A.size()>B.size();//判断A的位数是否大于B的位数
for(int i=A.size();i>=0;i--)//位数一样,将每一位依次比较
if(A[i]!=B[i])//如果这一位两个数不同
return A[i]>B[i];//判断这一位是否有A>B
return 1;//A=B是也返回true
}
vector<int> sub(vector<int> &A,vector<int> &B)
{
vector<int> C;
int t=0,al=A.size(),bl=B.size();//t记录当前位计算的数,并且判断是否有借位
for(int i=0;i<al;i++)
{
t=A[i]-t;//先减去借位
if(i<bl)//当前位数小于B的位数
t-=B[i];//减去当前位的B
C.push_back((t+10)%10);//当不需要借位时,计算完t肯定是个大于等于0的个位数,%10取的是个位数,所以+10不影响。
//当需要借位时,t肯定是个负数,借位+10后就是所得结果
if(t<0) t=1;//当t为负数时代表要借位
else t=0;
}
while(C.size()>1&&C.back()==0)//去掉前导0
C.pop_back();
return C;
}
string s1,s2;
vector<int> A,B,C;
int main()
{
cin>>s1>>s2;
for(int i=s1.size()-1;i>=0;i--)
A.push_back(s1[i]-'0');
for(int i=s2.size()-1;i>=0;i--)
B.push_back(s2[i]-'0');
if(cmp(A,B))//当A大于B时(绝对值)
C=sub(A,B);
else
{
C=sub(B,A);
cout<<"-";
}
for(int i=C.size()-1;i>=0;i--)
cout<<C[i];
return 0;
}
三、高精度乘法——大数*小数情况
1、思路
我们将较小的乘数看成一个整体(int类型),然后去乘较大的数(string类型)
2、代码
#include<iostream>
#include<vector>
using namespace std;
vector<int> mul(vector<int> &A,int b)
{
vector<int> C;
int t=0,al=A.size();
for(int i=0;i<al||t;i++)//当没有遍历完A的时候或者到最后进位没有进完时
{
if(i<al)
t+=A[i]*b;
C.push_back(t%10);
t/=10;
}
while(C.size()>1&&C.back()==0)//去除前导0,刚开始不知道哪来的前导0,wa了一次才知道,当有个乘数为0时乘积就是一堆0
C.pop_back();
return C;
}
string s;
int b;
vector<int> A,C;
int main()
{
cin>>s>>b;
for(int i=s.size()-1;i>=0;i--)
A.push_back(s[i]-'0');
C=mul(A,b);
for(int i=C.size()-1;i>=0;i--)
cout<<C[i];
return 0;
}
四、高精度除法
1、思路
2、代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> div(vector<int> &A,int b,int &r)//b是除数,r是余数
{
vector<int> C;
r=0;//刚开始余数为0
for(int i=A.size()-1;i>=0;i--)
{
r=r*10+A[i];//上一位的余数*10加上这一位数
C.push_back(r/b);//将商向下取整记录
r%=b;//记录余数
}
reverse(C.begin(),C.end());//由于是逆序输入的,用reverse反转过来
while(C.size()>1&&C.back()==0)//去除前导0
C.pop_back();
return C;
}
int main()
{
string a;
int b;
cin>>a>>b;
vector<int> A,C;
for(int i=a.size()-1;i>=0;i--)
A.push_back(a[i]-'0');
int r;
C=div(A,b,r);
for(int i=C.size()-1;i>=0;i--)
printf("%d",C[i]);
cout<<endl<<r<<endl;
return 0;
}