题目要求:
两个数使用string 表示,请实现一个函数,将他们相加。
注意:
1. 该数可能包含小数,比如:123.07+8796
2. 输入可能有误,请检查是否合法,不合法返回值为false
3. 该数不包含科学计数法。
关键在于提取字符串中的数字信息,然后分辨数字的合法性。比如02+1.2,2.+2,2.3+.2等等不合法情况。主要思路是首先提取符号“.”和“+”的位置,为提取数字做准备,记录符号位置以后,就可以提取一个个单独数字构成一个数。细节中要注意“.”的问题,可能存在一个,且在加号前或者后,可能不存在,可能同时存在两个,一个在加号前,一个在加号后。
附上自己写的代码,仅供参考:
#include<iostream>
#include<cmath>
#include<string>
using namespace std;
int main()
{
string a;
int i,d,k=0,p=0,l1=0,l2=0; //k为加号位置,l1为第一个小数点位置,l2记录的二个小数点的位置,p记录加符号的数量
double q,b,c; //q为第一个数,b为第二个数,c为结果
cin>>a;
d=a.length();
for(i=0;i<=d-1;++i)
{
if((a[i]>='0'&&a[i]<='9')||a[i]=='+'||a[i]=='-'||a[i]=='*'||a[i]=='/'||a[i]=='.')//所选字符符合范围
{
if(a[i]=='.') //小数点
{
if(k!=0&&l2==0&&(i-k)!=1) //判断条件依次为在K之后,l2只有一个,k和l2不相邻
l2=i;
else if(k==0&&l1==0)//同理如上
l1=i;
else {cout<<"false";return 0;} //否则不满足以上条件,判断小数点位置不合理
}
else if(a[i]=='+'||a[i]=='-'||a[i]=='*'||a[i]=='/')//扩展一下,加减乘除
{k=i;++p;}
}
else {cout<<"false";return 0;}
}
if(l1==0)//第一个数为整数(无第一个小数点)
{
for(i=0;i<k;++i)
q+=(a[i]-48)*pow(10,k-i-1);}
else{for(i=0;i<l1;++i)
q+=(a[i]-48)*pow(10,l1-i-1);//第一个数的整数部分
for(i=l1+1;i<k;++i)
q+=(a[i]-48)*pow(10,l1-i);}//第一个数的小数部分
if(l2==0)//第二个数为整数(无第二个小数点)
{
for(i=k+1;i<=d-1;++i)
b+=(a[i]-48)*pow(10,d-i-1);}
else{for(i=k+1;i<l2;++i)
b+=(a[i]-48)*pow(10,l2-i-1);//第二个数的整数部分
for(i=l2+1;i<=d-1;++i)
b+=(a[i]-48)*pow(10,l2-i);}//第二个数的小数部分
if((a[0]=='0'&&l1!=1)||(a[k+1]=='0'&&l2!=k+2)||p!=1||l2==d-1||(l1!=0&&l1==k-1))//这个一个重点,在代码后讨论
cout<<"false"<<"1";
else
{if(a[k]=='+')
c=q+b;
else if(a[k]=='-')
c=q-b;
else if(a[k]=='*')
c=q*b;
else if(a[k]=='/')
c=q/b;
cout<<c;}
return 0;
}
接着讨论if((a[0]<49||a[0]>57||p!=1||l2==d-1)||(l1!=0&&l1==k-1)),第一个括号里的内容容易理解,判断条件依次为 ①第一个位置为0时排除错误情况(012+1错误,0.12+1正确)②算术符号后边为0时排除错误情况(12+012错误,12+0.12正确)③加号有且仅有一个④第二个小数点不在最后(如2+2.,小数点在最后,不符合要求)⑤其实这个条件是为了排除第一个小数点和加号连在一起的情况(如2.+3,不符合要求),此时有人会说直接用l1==k-1不就行了?这样做会有一个问题,注意l1和K都是由用户决定的,因此有很大的不确定性,采用这种约束条件不符合一个优秀程序员的设计模式。针对于这种情况,如果只有l1==k-1,会发生一种情况:当l1为0,k为1时(即2+2),系统也会判断出错。因此完整条件应该是(l1!=0&&l1==k-1)。
最后,再提供一种有趣的思路,那就是采用正则表达式,利用regex库。
regex r(“(\d+).?(\d+)+-.?(\d+)”);//采用默认的ECMAScript标准
smatch m;
if(regex_match(str,r))
int a=atoi(m[1].str().cstr());//提取第一个捕捉组(\d+)的内容,并保存为int型
……
大家可以评论交流一下。