近日,做了一道阿里给的大数相加的编程题。题目大意如下:
输入两个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;
}
运行结果:
其中,部分代码仍可进行优化(博主比较懒...就没继续了),如判断是否带小数的判断以及后续的函数整合等。