【题目】
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串 “+100”, “5e2”, “-123”, “3.1416”和 “-1E-16”都表示数值。 但是 “12e”, “1a3.14”, “1.2.3”, “+-5”和 “12e+4.3”都不是。
【基本思路】
字符串应满足通式A[.[B]][e|EC],或者.B[e|EC]。其中,A、C表示有(或无)符号位的数字,B表示无符号位的数字。在小数里可能没有整数部分。例如:.123等于0.123。因此,A部分不是必须的。如果一个数没有整数部分,那么它的小数部分不能为空。
遍历字符串,首先找到满足条件的A部分(可能不存在);如果遇到 ‘.’,则开始寻找满足条件的B部分。如果遇到 ‘e’或者 ‘E’,则开始寻找满足条件的C部分。如果前面的部分能组成数字,最后判断字符串是否已经到达结尾即可。
【代码实现】
class Solution {
public:
bool isNumeric(char* string)
{
if(string == nullptr){
return false;
}
bool isNum = scanInteger(&string);
if(*string == '.'){
string++;
//为什么用||?
//1、小数可以没有整数部分,如:.123等于0.123
//2、小数点后面可以没有数字,如:233.等于233.0
//3、小数点前面后面可能都有数字,如:123.123
isNum = scanUnsignedInteger(&string) || isNum; //位置不可变,否则scanUnsignedInteger不执行
}
if(*string == 'e' || *string == 'E'){
string++;
//为什么用&&
//1、当e或E前面没有整数时,该字符串不能表示数字,如:.e1、e1
//2、当e或E后面没有整数时,该字符串不能表示数字,如:12e、12e+5.4
isNum = isNum && scanInteger(&string);
}
return isNum && *string == '\0';
}
bool scanUnsignedInteger(char** str){
char* before = *str;
while(**str != '\0' && **str >= '0' && **str <= '9'){
(*str)++;
}
return *str > before;
}
bool scanInteger(char** str){
if(**str == '+' || **str == '-'){
(*str)++;
}
return scanUnsignedInteger(str);
}
};