高精度加减乘除
加法
思想就是模拟加法的过程,我们先将两个数逆序之后进行操作,便于进位
/*
思想是模拟数据加减的过程
*/
#include<iostream>
#include<vector>
using namespace std;
vector<int> add (vector<int> &A,vector<int> &B)
//传地址可以减少数据再次复制
{
vector<int> C;
int t=0;
for(int i=0,j=0;i<A.size()||j<B.size();i++,j++)
{
if(i<A.size()) t+=A[i];
if(j<B.size()) t+=B[j];
C.push_back(t%10);
t=t/10;
}
if(t) C.push_back(t);
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);//auto可以保持与后面数据一样的数据类型
for(int i=C.size()-1;i>=0;i--)
cout << C[i];
return 0;
}
减法
相比于加法,减法稍微复杂一点
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
bool cmp(vector<int>&A,vector<int>&B)
{
//这个处理很妙,先比较是否一样长,在根据判断结果决定是否逐个比较
if(A.size()!=B.size()) return A.size()>B.size();
for(int i=A.size();i>=0;i--)
if(A[i]!=B[i]) return A[i]>B[i];
return true;
}
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=t-B[i];
C.push_back((t+10)%10);
//这一步也很巧妙
if(t<0) t=1;
else t=0;
}
while(C.size()>1&&C.back()==0) C.pop_back();
/*这一步是为了去掉前导0
C.back()是指最后一位数,即结果的最高位*/
return C;
}
int main()
{
string a,b;
cin>>a>>b;
vector<int> A,B,C;
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))
{
C=sub(A,B);//使得A永远是最大的数,便于模拟减法过程
for(int i=C.size()-1;i>=0;i--)
cout<<C[i];
}
else
{
C=sub(B,A);
printf("-");
for(int i=C.size()-1;i>=0;i--)
cout<<C[i];
}
return 0;
}
这里感觉到了如何将代码写的简洁,尤其是模拟部分真的很妙
乘法
这个题目要注意的是虽然依然是模拟乘法的过程,但是由于B这个乘数并不大,所以直接用B这个整体去乘,而不是一位位的乘;
然后思路跟前面差不多
#include<iostream>
#include<vector>
using namespace std;
vector<int> chen(vector<int>&A,int B)
{
vector<int>C;
int t=0;
for(int j=0;j<A.size();j++)
{
C.push_back((B*A[j]+t)%10);
t=(B*A[j]+t)/10;
}
if(t>0) C.push_back(t);
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');
vector<int>C;
C=chen(A,B);
for(int i=C.size()-1;i>=0;i--)
cout<<C[i];
return 0;
}
除法
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int t=0;
vector<int> div(vector<int>& A,int b)
{
vector<int>C;
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();//去掉前导0
return C;
}
int main()
{
string a;
cin>>a;
int b;
cin>>b;
vector<int>A;
for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
auto C=div(A,b);
for(int i=C.size()-1;i>=0;i--)
cout<<C[i];
cout<<endl<<t;
return 0;
}
我觉得主要是理解模拟手算的过程