您的位置:首页 > 其它

大数减法

2014-02-02 14:52 309 查看
描述

给定任意位数长度的两个数,求它们数值之差。

输入

每个测试用例含有两个数,代表两个任意位数长度的数A,B.

输出

计算出这两个任意位数长度的数之差A-B。

样例输入

123451234512345   543215432154321

54.321 12.345  

样例输出

-419764197641976

41.976

#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<<StringSubtract(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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: