主函数模板
加减法模板
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>a,b;
int main(){
string s1,s2;
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');
//-----------------------------------
// 加法使用
vector<int>c=add(a,b);
// 减法使用
if(cmp(a,b))
c=sub(a,b);
else {
cout<<"-";
c=sub(b,a);
}
//-----------------------------------
for(int i=c.size()-1;i>=0;i--)cout<<c[i];
}
乘除法模板
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>a;
int main(){
string s1;
int num,k;
cin>>s1>>num;
for(int i=s1.size()-1;i>=0;i--)a.push_back(s1[i]-'0');
// 除法使用
vector<int>c=div(a,num,k);
// 乘法使用
vector<int>c=mul(a,num);
// 公用
for(int i=c.size()-1;i>=0;i--)cout<<c[i];
// 除法使用
cout<<endl<<k;
}
高精度加法(len+len)
算法模拟:若num1=1237,num2=99876
,存储的时候a[]={7,3,2,1}.b[]={6,7,8,9,9}
- 开始t=0
- 第一轮循环
t=13,c[]={3},t=1
- 第二轮循环
t=11,c[]={3,1},t=1
- 第三轮循环
t=11.c[]={3,1,1},t=1
- 第四轮循环
t=11,c[]={3,1,1,1},t=1
- 第五轮循环
t=10,c[]={3,1,1,1,0},t=0
- 结束循环,因为
t=1
,所以继续加入c中,所以c[]={3,1,1,1,0,1}
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++){
if(i<a.size())t+=a[i]; // 若a没有越界,则加上a[i]
if(i<b.size())t+=b[i]; // 若b没有越界,则加上b[i]
c.push_back(t%10); // 将t的低位加入c中
t/=10;
}
if(t==1)c.push_back(1); // 判断最大的两个数是否有进位
return c;
}
高精度减法(len-len)
减法要相对复杂的多,首先需要比较两个数的大小,代码如下
bool cmp(vector<int>a,vector<int>b){
if(a.size()!=b.size())return a.size()>b.size(); // 若两者位数不同,则比较位数大小
for(int i=a.size()-1;i>=0;i--){ // 若位数不同,则依次从高位开始比较大小
if(a[i]!=b[i])
return a[i]>b[i];
}
return true; // 位数,每位大小都相同,返回true
}
若a>=b
,则调用sub(a,b)
,若a<b
,则输出'-1'
,调用sub(b,a)
。
sub
函数代码如下:
vector<int> sub(vector<int>a,vector<int>b){
vector<int>c;
int t=0; // 进位
for(int i=0;i<a.size();i++){
t=a[i]-t;
if(i<b.size())t-=b[i];
c.push_back((t+10)%10); // 此时t有可能<0,则需要借位,
// 上述代码等价于
// if(t<0)c.push_back((t+10)%10);
// else c.push_back(t%10);
if(t<0)t=1;
else t=0;
}
while(c.size()>1 && c.back()==0)c.pop_back(); //去掉前缀0
return c;
}
算法模拟:若num1=3223,num2=3333
,存储的时候a[]={3,2,2,3}.b[]={3,3,3,3}
- 开始t=0
- 第一轮循环
t=0,c[]={0},t=0
- 第二轮循环
t=1,c[]={0,1},t=0
- 第三轮循环
t=1,c[]={0,1,1}.t=0
- 第四轮循环
t=0,c[]={0,1,1,0},t=0
- 进入
while
循环,则c[]={0,1,1}
高精度乘法(len*num)
vector<int> mul(vector<int>a,int num){
vector<int>c;
int t=0; // 进位
for(int i=0;i<a.size()||t;i++){
if(i<a.size())t+=a[i]*num;
c.push_back(t%10);
t/=10;
}
while(c.size()>1 && c.back()==0)c.pop_back(); //删除前缀0
return c;
}
算法模拟:若num1=1234,num2=12
,存储的时候a[]={4,3,2,1},num=12
- 开始t=0
- 第一轮循环
t=48,c[]={8},t=4
- 第二轮循环
t=40,c[]={8,0},t=4
- 第三轮循环
t=28,c[]={8,0,8},t=2
- 第四轮循环
t=14.c[]={8,0,8,4},t=1
- 第五轮循环(
a
已经越界,但t
不为0),t=1,c[]={8,0,8,4,1},t=0
- 结束循环直接返回(不需要删除前缀0,一般只有
num=0
才需要)
高进度除法(len/num)
vector<int> div(vector<int>a,int num,int &k){
vector<int>c;
int t=0; // 进位
for(int i=a.size()-1;i>=0;i--){
t=t*10+a[i];
c.push_back(t/num);
t%=num;
}
k=t;
reverse(c.begin(),c.end());
while(c.size()>1 && c.back()==0)c.pop_back();
return c;
}
除法与加减乘法不同,可以从高位开始存储,但为了与加减乘法兼容,则这里还是从低位存储,但是计算时候从高位计算
算法模拟:若num1=1234,num2=12
,存储的时候a[]={4,3,2,1},num=12
- 开始
t=0
- 第一轮循环
t=1,c={0},t=1
- 第二轮循环
t=12,c={0,1},t=0
- 第三轮循环
t=3,c={0,1,0},t=3
- 第四轮循环
t=34,c={0,1,0,2},t=10
- 这里也需要去掉前缀0,但是必须先
reverse
才能去掉前缀和,返回的c
正好是倒序