描述
给定任意位数长度的两个数,求它们数值之和。
输入
每个测试用例含有两个数,代表两个任意位数长度的数A,B.
输出
计算出这两个任意位数长度的数之和。
样例输入
123451234512345 543215432154321
12.345 54.321
12.345 54.321
样例输出
666666666666666
66.666
66.666
#include<iostream>
#include<string>
using namespace std;
void Change(string &a);
string StringAdd(string a,string b,bool NeedCheck=1);
string StringSubtract(string a,string b,bool NeedCheck=1);
int main(){
string a,b;
while(cin>>a>>b)
cout<<StringAdd(a,b)<<endl;
return 0;
}
void Change(string &a){
//该函数将把字符串数字化为最简形式,若不为数字,化为0
int len=a.length(),i,flag=0;
//len:字符串长度 i:循环变量 flag:小数点个数
if(a[0]=='+' && (a[1]>='0' && a[1]<='9'))
a[0]='0';
else if((a[0]=='-' && (a[1]>='0' && a[1]<='9')) || (a[0]>='0' && a[0]<='9'))
;
else{
a="0";
return;
}
//检测开头是否为数字或符号
for(i=1;i<len;i++){
if((a[i]>='0' && a[i]<='9'))
;
else if(flag<1 && a[i]=='.') //小数点最多为一个
flag++;
else{
a="0";
return;
}
}
//检测数字
len--;
while(flag && a[len]=='0'){
a.erase(len,1);
len--;
}
if(a[len]=='.')
a.erase(len,1);
while(a.length()>1 && a[0]=='0'){
a.erase(0,1);
}
//去除前置0和后置0
}
string StringAdd(string a,string b,bool NeedCheck){
//该函数执行字符串加法,a,b为加数
//若加上参数0,则不进行是否为数字的检测,可能会出现错误
if(NeedCheck){
Change(a);
Change(b);
}
//检测是否为数字并化为最简形式
bool IsNegative;
if(a[0]=='-' && b[0]=='-'){
a.erase(0,1);
b.erase(0,1);
IsNegative=1;
}
else if(a[0]=='-' && b[0]!='-'){
a.erase(0,1);
return StringSubtract(b,a,0);
}
else if(a[0]!='-' && b[0]=='-'){
b.erase(0,1);
return StringSubtract(a,b,0);
}
//根据数学规律转化运算情况,以下代码仅适用于正数加法
int carry=0,i,result,maxlen,len;
string sumPart1,sumPart2,aPart1,aPart2,bPart1,bPart2,sum;
//carry:是否需要进位 result:中间结果
//在字符串变量后加的Part1为整数部分,Part2为小数部分,sum:结果
if(a.find(".")==string::npos)
a+=".0";
if(b.find(".")==string::npos)
b+=".0";
aPart1=a.substr(0,a.find("."));
aPart2=a.substr(a.find(".")+1);
bPart1=b.substr(0,b.find("."));
bPart2=b.substr(b.find(".")+1);
//若没小数则转化为小数
maxlen=aPart2.length()>bPart2.length()?aPart2.length():bPart2.length();
len=aPart2.length();
while(len<maxlen){
aPart2+="0";
len++;
}
len=bPart2.length();
while(len<maxlen){
bPart2+="0";
len++;
}
len=sumPart2.length();
while(len<maxlen){
sumPart2+="0";
len++;
}
for(i=maxlen-1;i>=0;i--){
result=aPart2[i]+bPart2[i]-2*'0'+carry;
sumPart2[i]=result%10+'0';
carry=result/10;
}
maxlen=aPart1.length()>bPart1.length()?aPart1.length()+1:bPart1.length()+1;
len=aPart1.length();
while(len<maxlen){
aPart1="0"+aPart1;
len++;
}
len=bPart1.length();
while(len<maxlen){
bPart1="0"+bPart1;
len++;
}
len=sumPart1.length();
while(len<maxlen){
sumPart1="0"+sumPart1;
len++;
}
for(i=maxlen-1;i>0;i--){
result=aPart1[i]+bPart1[i]-2*'0'+carry;
sumPart1[i]=result%10+'0';
carry=result/10;
}
sumPart1[0]=carry+'0';
sum=sumPart1+"."+sumPart2;
//先进行小数部分的运算再进行整数部分的运算
maxlen=sum.length()-1;
while(sum[maxlen]=='0'){
sum.erase(maxlen,1);
maxlen--;
}
if(sum[maxlen]=='.')
sum.erase(maxlen,1);
while(sum.length()>1 && sum[0]=='0'){
sum.erase(0,1);
}
//去除前置0和后置0
return sum;
}
string StringSubtract(string a,string b,bool NeedCheck){
//该函数执行字符串减法法,a,b为被减数,减数
//若加上参数0,则不进行是否为数字的检测,可能会出现错误
if(NeedCheck){
Change(a);
Change(b);
}
//检测是否为数字并化为最简形式
if(a[0]=='-' && b[0]=='-'){
swap(a,b);
a.erase(0,1);
b.erase(0,1);
}
else if(a[0]=='-' && b[0]!='-'){
a.erase(0,1);
return "-"+StringAdd(a,b,0);
}
else if(a[0]!='-' && b[0]=='-'){
b.erase(0,1);
return StringAdd(a,b,0);
}
//根据数学规律转化运算情况,以下代码仅适用于正数减法
int carry=0,i,maxlen,len;
string sumPart1,sumPart2,aPart1,aPart2,bPart1,bPart2,sum;
bool IsNegative;
//carry:是否需要进位
//在字符串变量后加的Part1为整数部分,Part2为小数部分,sum:结果
if(a.find(".")==string::npos)
a+=".0";
if(b.find(".")==string::npos)
b+=".0";
aPart1=a.substr(0,a.find("."));
aPart2=a.substr(a.find(".")+1);
bPart1=b.substr(0,b.find("."));
bPart2=b.substr(b.find(".")+1);
//若没小数则转化为小数
maxlen=aPart2.length()>bPart2.length()?aPart2.length():bPart2.length();
len=aPart2.length();
while(len<maxlen){
aPart2+="0";
len++;
}
len=bPart2.length();
while(len<maxlen){
bPart2+="0";
len++;
}
len=sumPart2.length();
while(len<maxlen){
sumPart2+="0";
len++;
}
maxlen=aPart1.length()>bPart1.length()?aPart1.length():bPart1.length();
len=aPart1.length();
while(len<maxlen){
aPart1="0"+aPart1;
len++;
}
len=bPart1.length();
while(len<maxlen){
bPart1="0"+bPart1;
len++;
}
len=sumPart1.length();
while(sumPart1.length()<maxlen){
sumPart1="0"+sumPart1;
len++;
}
if(aPart1+aPart2<bPart1+bPart2){
swap(aPart1,bPart1);
swap(aPart2,bPart2);
IsNegative=1;
}
else
IsNegative=0;
//判断结果正负,并根据数学规律转化运算情况,以下代码仅适用于大数减小数
maxlen=aPart2.length();
for(i=maxlen-1;i>=0;i--){
if(aPart2[i]-carry>=bPart2[i]){
sumPart2[i]=aPart2[i]-carry-bPart2[i]+'0';
carry=0;
}
else{
sumPart2[i]=aPart2[i]-carry-bPart2[i]+10+'0';
carry=1;
}
}
maxlen=aPart1.length();
for(i=maxlen-1;i>=0;i--){
if(aPart1[i]-carry>=bPart1[i]){
sumPart1[i]=aPart1[i]-carry-bPart1[i]+'0';
carry=0;
}
else{
sumPart1[i]=aPart1[i]-carry-bPart1[i]+10+'0';
carry=1;
}
}
sum=sumPart1+"."+sumPart2;
//先进行小数部分的运算再进行整数部分的运算
maxlen=sum.length()-1;
while(sum[maxlen]=='0'){
sum.erase(maxlen,1);
maxlen--;
}
if(sum[maxlen]=='.')
sum.erase(maxlen,1);
while(sum.length()>1 && sum[0]=='0')
sum.erase(0,1);
//去除前置0和后置0
if(IsNegative)
return "-"+sum;
return sum;
}