高精度算法的代码思路:模拟竖式计算
加法
洛谷P1601 A+B Problem(高精)
题目描述
高精度加法,相当于 a+b problem,不用考虑负数。
输入格式
分两行输入。 a , b ≤ 1 0 500 a,b \leq 10^{500} a,b≤10500。
输出格式
输出只有一行,代表
a
+
b
a+b
a+b 的值。
样例 #1
样例输入 #1
1
1
样例输出 #1
2
样例 #2
样例输入 #2
1001
9099
样例输出 #2
10100
代码实现
#include<iostream>
#include<vector>
using namespace std;
vector<int> A,B;//vec不容易越界
vector<int> add(vector<int>A,vector<int>B)//vec传参格式
{
int t=0;//储存进位
int lena=A.size(),lenb=B.size();//存储长度 优化
vector<int>C;
for(int i=0,j=0;i<lena||j<lenb||t;i++,j++)//i,J分别对应A,B指针
//当A,B其中一个没有将所有数位加完,或进位没有进完时,还要继续加下去
{
if(i<lena)
{
t+=A[i];
}
if(j<lenb)
{
t+=B[j];
}
C.push_back(t%10);//模拟竖式,最大9*9=81,两位数,所以模10取个位
t/=10;//进位
}
return C;
}
int main()
{
string a,b;
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');
vector<int>C=add(A,B);
for(int i=C.size()-1;i>=0;i--)
{
cout<<C[i];
}
return 0;
}
减法
洛谷P2142 高精度减法
题目描述
高精度减法。
输入格式
两个整数 a , b a,b a,b(第二个可能比第一个大)。
输出格式
结果(是负数要输出负号)。
样例 #1
样例输入 #1
2
1
样例输出 #1
1
提示
- 20 % 20\% 20% 数据 a , b a,b a,b 在 long long 范围内;
- 100 % 100\% 100% 数据 0 < a , b ≤ 1 0 10086 0<a,b\le 10^{10086} 0<a,b≤1010086。
代码实现
#include<iostream>
#include<vector>
using namespace std;
vector<int> A,B;
int check(string a,string b)
//减法要新写函数来判断大小
{
if(a.size()!=b.size())//如果a和b长度不一样
{
return a.size() > b.size();//返回长度更长的那个
}
for(int i=0;i<a.size();i++)//如果一样,找到不一样的那个
{
if(a[i]!=b[i])
{
return a[i]>b[i]; //返回同数位上,数更大的那个
}
}
return 1;//如果a>b 返回1
}
vector<int> sub(vector<int>A,vector<int>B)
{
int r=0;//存储借位
int lena=A.size(),lenb=B.size();
vector<int>C;
for(int i=0,j=0;i<lena;i++,j++)//减法的循环次数不会超过大数位数
{
r=A[i]-r;//减数借位
if(j<lenb)
{
r-=B[j];
}
C.push_back((r+10)%10);//有可能r是负数,所以+10再取模
r=(r>=0?0:1);
//if(r>=0) return 0 else return 1
}
while(C.size()>1&&C.back()==0) C.pop_back(); //去掉高位的0
return C;
}
int main()
{
string a,b;
cin>>a>>b;
if(!check(a,b)) swap(a,b),cout<<"-";
//如果a<b ab交换位置再进行计算,且要输出负号
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<int>C=sub(A,B);
for(int i=C.size()-1;i>=0;i--)
{
cout<<C[i];
}
return 0;
}
乘法
洛谷P1303 A*B Problem
题目描述
给出两个非负整数,求它们的乘积。
输入格式
输入共两行,每行一个非负整数。
输出格式
输出一个非负整数表示乘积。
样例 #1
样例输入 #1
1
2
样例输出 #1
2
提示
每个非负整数不超过 1 0 2000 10^{2000} 102000。
代码实现
#include<bits/stdc++.h>
using namespace std;
vector<int>A,B;
vector<int> mul(vector<int>A,vector<int>B)
{
int lena=A.size(),lenb=B.size();
vector<int> C(lena+lenb);//C的长度是lena+lenb
for(int i=0;i<lena;i++)//乘法模拟竖式,需要双重循环
{
for(int j=0;j<lenb;j++)
{
C[i+j]+=A[i]*B[j];//结果的第i+j位,是Ai和Bj的指针之和
C[i+j+1]+=C[i+j]/10;//下一位+上 上一位的进位
C[i+j]%=10;//进位后取模 保留个位
}
}
while(C.size()>1&&C.back()==0) C.pop_back(); //去除高位0
return C;
}
int main()
{
string a,b;
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');
vector<int>C=mul(A,B);
for(int i=C.size()-1;i>=0;i--)
{
cout<<C[i];
}
return 0;
}
除法
洛谷P1480 A/B Problem
题目描述
输入两个整数 a , b a,b a,b,输出它们的商。
输入格式
两行,第一行是被除数,第二行是除数。
输出格式
一行,商的整数部分。
样例 #1
样例输入 #1
10
2
样例输出 #1
5
提示
0 ≤ a ≤ 1 0 5000 0\le a\le 10^{5000} 0≤a≤105000, 1 ≤ b ≤ 1 0 9 1\le b\le 10^9 1≤b≤109。
代码实现
#include<bits/stdc++.h>
using namespace std;
vector<int>A;
vector<int> div(vector<int>A,int b)
{
long long r=0;//存储余数
//防止越界,使用long long类型
vector<int>C;
for(int i=A.size()-1;i>=0;i--)
//除法是正着除,输入是倒着的,所以倒着循环
{
r=r*10+A[i];//上一次的余数+这一次的数=这一次的被除数
C.push_back(r/b);
r=r-r/b*b;//减去商*除数,就是余数
}
reverse(C.begin(),C.end());//倒着输出
while(C.size()>1&&C.back()==0) C.pop_back(); //去除高位0
return C;
}
int main()
{
string a;
int b;//被除数不是高精度,所以直接用int
cin>>a>>b;
for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
vector<int>C=div(A,b);
for(int i=C.size()-1;i>=0;i--)
{
cout<<C[i];
}
return 0;
}
1118

被折叠的 条评论
为什么被折叠?



