表示数值的字符串
题目: 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)
例如,字符串"+100"、“5e2”、"-123"、“3.1416"以及”-1E-16"都表示数值,
但"12e"、“1a3,14”、“1.2.3”、"±5"以及"±5"和"12e5.4"都不是
表示模式
可以总结出表示的数值的字符串模式为
A[.[B]][e|EC] 或者.B[e|EC]
其中A为数值的整数部分,B紧跟着小数点为数值的小数部分,C紧跟着’e’或者’E’为数值的指数部分。
在小数里可能没有数值的整数部分。例如,小数.123等于0.123。因此A部分不是必须的,如果一个数没有整数部分,那么它的小数部分不能为空
上述A和C都是可能以"+“或者”-"开头的0~9的数位串;B也是0 ~ 9的数位串,但是前面不能有正负号
方法
判断一个字符串是否符合上述模式时,首先尽可能多的扫描0~9的数位(有可能在起始处有’+‘或者’-’),也就是钱买你的模式中表示数值整数的A部分。
如果遇到小数点’.’,则开始扫描表示数值小数的B部分。如果遇到’e’或者’E’,则开始扫描C部分
代码
bool isNumberic(const char* str)
{
if(str==nullptr)
return false;
bool numeric=scanInteger(&str);
//如果出现'.',则接下来时数字的小数部分
if(*str=='.')
{
++str;
/*下面一行代码用||的原因
1、小数可以没有整数部分
2、小数点后面可以没有数字,如233.和2333.0
3、当然,小数点前面和后面可以都有数字,如2333.666
*/
numeric=scanUnsignedInteger(&str)||numeric;
}
//如果出现'e'或者'E',则接下来时数字的指数部分
if(*str=='e' || *str=='E')
{
++str;
/*下面一行用&&的原因
1、当e或者E前面没有数字时,整个字符串并不能表示数字,如.e1、e1;
2、当e或者E后面没有整数时,整个字符串不能表示数字,如12e、12e+5.4
*/
numeric==numeric&&scanInteger(&str);
}
return numeric && *str=='\0';
}
//用来扫描字符串中0~9的数位,可以用来匹配前面数值模式中的B部分
bool scanUnsignedInteger(const char** str)
{
const char* before=*str;
while(**str!='\0' && **str>='0' && **str<='9')
++(*str);
//当str中存在若干0~9的数字时,返回true
return *str>before;
}
//扫描可能以表示正负的'+'或者'-'为起始的0~9的数位(类似一个可能带正负符号的整数)
bool scanInteger(const char** str)
{
if(**str=='+' || **str=='-')
++(*str);
return scanUnsignedInteger(str);
}
——————————————————————————————————————————————————————
参考书籍《剑指offer》