C++实现string类型的大数相加(带小数)
近日,做了一道阿里给的大数相加的编程题。题目大意如下:
输入两个string类型的数,如12.223 11,判断输入字符串是否合法。合法则输出true以及相加结果(true 23.223),非法则输出false """"。
期间几经修改,在判断合法方面排除了如.212以及122.这种错误(出现除数字以及.以外的错误亦已排除)。
主要的思路是将小数与整数部分进行分离,分别相加。由于小数部分可能想整数部分进位,需要进行进位判断。
完整代码如下:
#include <iostream> #include <string> using namespace std; string max_i,min_i; bool carry_dem = false; //判断小数是否需要向整数进位 void count_int(string s1,string s2) //计算整数部分的和 { max_i = s1;min_i = s2; if(s2.size()>s1.size()) { max_i = s2; //取长度大的数为max min_i = s1; } if(carry_dem) //完成进位 max_i[max_i.size() -1] ++; for(int i = min_i.size()-1,j = max_i.size()-1; i>=0;i--,j--) //模拟整数加的过程 { max_i[j] += min_i[i] -'0'; //选择将结果保存在max变量中 if(max_i[j] > '9') { if(j > 0) { max_i[j - 1] ++; max_i[j] -= 10; } else { max_i = "1" + max_i; max_i[j] -= 10; } } } } string max_d,min_d; void count_dem(string s1,string s2) //对小数部分进行相加 { max_d = s1;min_d = s2; if(s2.size()>s1.size()) { max_d = s2; min_d = s1; } for(int i=min_d.size()-1;i>=0;i--) { max_d[i] += min_d[i] -'0'; if(max_d[i] > '9') { if(i > 0) { max_d[i - 1] ++; max_d[i] -= 10; } else { carry_dem = true; //设置进位标志 max_d[i] -= 10; } } } } int main(){ string s1,s2; cin>>s1>>s2; int i,j,k; bool legal = true; for(i = 0; i< s1.size();i++) //完成字符串是否合法的判断 { if(((s1[i]<'0'||s1[i]>'9')&&(s1[i] != '.'))||(s1[s1.size()-1] == '.')||(s1[0] == '.')) legal = false; } for(i = 0; i< s2.size();i++) { if(((s2[i]<'0'||s2[i]>'9')&&(s2[i] != '.'))||(s2[s2.size()-1] == '.')||(s2[0] == '.')) legal = false; } string integer_1,integer_2; //取出字符串的整数部分 string demical_1,demical_2; //取出字符串的小数部分 if(!legal) cout<<"false "<<"\"\"\"\""; else { bool wi_dem1 = false,wi_dem2 = false; //判断是否带小数 int pos_s1 = 0,pos_s2 = 0; for(i = 0; i< s1.size();i++) if(s1[i] == '.') { wi_dem1 = true; } for(i = 0; i< s2.size();i++) if(s2[i] == '.') { wi_dem2 = true; } if((!wi_dem1)&&(!wi_dem2)) //两个数均不带小数部分 { count_int(s1,s2); cout<<"true "<<max_i; } else { if(wi_dem1) //第一个数带小数时分离整数、小数部分 { pos_s1 = s1.find("."); integer_1 = s1.substr(0,pos_s1); demical_1 = s1.substr(pos_s1+1); } if(wi_dem2) //第二个数带小数时分离整数、小数部分 { pos_s2 = s2.find("."); integer_2 = s2.substr(0,pos_s2); demical_2 = s2.substr(pos_s2+1); } if(wi_dem2 && wi_dem1) //均带小数 { count_dem(demical_1,demical_2); count_int(integer_1,integer_2); cout<<"true "<<max_i<<"."<<max_d; } else if(!wi_dem2 && wi_dem1) { count_int(integer_1,s2); cout<<"true "<<max_i<<"."<<demical_1; } else { count_int(integer_2,s1); cout<<"true "<<max_i<<"."<<demical_2; } } } return 0; }
运行结果:
其中,部分代码仍可进行优化(博主比较懒...就没继续了),如判断是否带小数的判断以及后续的函数整合等。