C++用实现大数模板(string、int128)
相加
string add(string a,string b) { //两数相加
string res="";
int i=1;
string first="0";
while(true) {
int tai=a.size()-i;
int tbi=b.size()-i;
if(tai<0 && tbi<0)
break; //从两数最右边开始模拟加法运算直到两数都遍历完
int ta,tb;
if(tai<0)
ta=0; //如果没数则至为0
else
ta=a[tai]-'0';
if(tbi<0)
tb=0; //如果没数则至为0
else
tb=b[tbi]-'0';
int temp=ta+tb+first[0]-'0'; //相加 first保存上一个的进位信息
first[0]=temp%10+'0'; //当前位是对10取余
res=first+res;
first[0]=temp/10+'0'; //进位是除10
i++;
}
if(first!="0")
res=first+res; //如果进位还有则添加
if(res[0]=='0' && res.size()>1) //去除前导0
res.erase(res.begin());
return res;
}
相乘
string mul(string a,string b) {
if(b.size()==1) { //如果b只有一位则使其分别相乘
string res="";
string first="0";
int mb=b[0]-'0';
for(int i=a.size()-1; i>=0; i--) { //从最后开始依次计算
int temp=(a[i]-'0') * mb + (first[0]-'0');
first[0]=temp%10+'0'; //当前位
res=first+res;
first[0]=temp/10+'0'; //进位
}
if(first!="0") {
res=first+res; //处理进位
}
if(res[0]=='0' && res.size()>1)
res.erase(res.begin()); //除去前导0
return res;
}
//否则则把b拆分为一位
string res="0";
string zero="";
for(int i=b.size()-1; i>=0; i--) { //从b的最后一位开始
string temp=mul(a,b.substr(i,1)); //计算当前为与a相乘
res=add(res,temp+zero); //在其后添加适当的0再与结果相加
zero=zero+"0";
}
return res;
}
整数转string
string inttostring(int m) { //将整数转为string
string res="";
string temp="0";
while(m) {
temp[0]=m%10+'0';
res=temp+res;
m/=10;
}
if(res=="")
res="0";
return res;
}
较大的值
string smax(string a,string b) {
if(a.size()>b.size())
return a;
if(a.size()<b.size())
return b;
return a>b?a:b;
}
时间复杂度比较高是个问题
考虑用long long拼接
struct int128 {
long long h;
long long l;
};
int128 max(int128 a,int128 b) {
if(a.h>b.h) return a;
if(a.h<b.h) return b;
if(a.l>b.l) return a;
if(a.l<b.l) return b;
return a;
}
int128 operator + (int128 a,int128 b) {
int128 k;
k.l=0,k.h=0;
k.l=a.l+b.l;
k.h=k.l/p+a.h+b.h;
k.l%=p;
return k;
}
int128 operator * (int128 a,int b) {
long long mod=1e9;
long long l1=a.l/mod;
long long l2=a.l%mod;
l1=l1*b+l2*b/mod;
l2=l2*b%mod;
a.h=a.h*b+l1/mod;
l1=l1%mod;
a.l=l1*mod+l2;
return a;
}