一般四类:大整数加法,减法,大整数乘小整数,大整数除以小整数
把大整数的每一位存到数组里面,因为int 和long long都存不下,存的时候大整数从后往前存,例如:大整数123456789,那么存的时候把9存到数组下标为0的地方,8存到数组下标为1的地方,其他依次,因为涉及到进位,最后输出的时候反过来输出就好了,数组用的vector。
一.大整数加法:
加法注意进位,将数字以字符串形式输入,然后再一个一个逆序放到vector里面,注意数字字符要变成整数(即减去'0'),可以自己在纸上模拟一下。
下边即实现A+B:
#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;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/=10;//比如说上边计算出两个数之和小于10,那么进位为零,大于10,进位为1
}
if(t) C.push_back(1);//全部都加完了,还有一个进位,那么就要在最高位上补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);//auto就是让编译器自己判断变量类型,这里等价于vector<int>C=add(A,B);
for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);//记得逆序输出
return 0;
}
二.大整数减法:
感觉减法明显比加法复杂啊啊啊啊,需要借位,还要令判两数大小,首先和加法一样先输入,存入vector,用bool函数判断A是不是比B大。
下边即实现A-B:
#include<iostream>
#include<vector>
using namespace std;
bool cmp(vector<int>&A,vector<int>&B)
{
if(A.size()!=B.size()) return A.size()>B.size();
else
{
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;
for(int i=0,t=0;i<A.size();i++)//t作为那个借位,刚开始时没有借位则t=0
{
t=A[i]-t;
if(i<B.size()) t-=B[i];//如果i比B的长度还大,B后边没数了,就是0,再减就没啥意义了那就不用减了
C.push_back((t+10)%10);//因为分为两种情况t>0和t<0,在这里的话(t+10)%10在t>0时还是t,在t<0时他要问别人借,由于他借来了一位,那么他就要加10.
if(t<0) t=1;
else t=0;
}
while(C.size()>1&&C.back()==0) C.pop_back();//去掉前导0,比方说123-120,结果应该为3,但是不去前导0的话就会输出003
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');
if(cmp(A,B))
{
auto C=sub(A,B);
for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
}
else
{
auto C=sub(B,A);
printf("-");
for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
}
return 0;
}
三.大整数乘一个小整数:
这个和加法有一点点类似,只是进位不只是1或者0.
下边即实现A*b:
#include<iostream>
#include<vector>
using namespace std;
vector<int> mul(vector<int>&A,int b)
{
vector<int>C;
int t=0;//t是进位
for(int i=0;i<A.size()||t;i++)
{
if(i<A.size()) t+=A[i]*b;//这里注意判断一下这个i是不是小于那个数组A的长度,超过了还加,那么加的就会是奇奇怪怪的东西
C.push_back(t%10);
t/=10;
}
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');//数字字符串逆序保存在A中,注意A中下标都是从0开始,到A.size()-1的;
if(b) C=mul(A,b);//特判一下,如果b不为0进行乘法
else C.push_back(0);//否则b等于0了,就只需要结果是一个0
for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
return 0;
}
四.大整数除以小整数:
感觉除法也会有些复杂,但是代码短呀呼呼呼,主要得拿纸上手模拟
下边即实现A除以b
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> div(vector<int>&A,int b,int &r)
{
vector<int>C;
for(int i=A.size()-1;i>=0;i--)//只有除法的时候是按照A中倒着来的,因为在纸上算的时候就是从前往后走
{
r=r*10+A[i];//在纸上算的时候拿下来一位,可以模拟一下
C.push_back(r/b);
r%=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;
vector<int>A;
for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
int r=0;
auto C=div(A,b,r);//r是余数
for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
cout<<endl<<r<<endl;
return 0;
}