题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+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都是可能以'+'和'-'开头的0~9的数位串,B是0~9的数位串,但前面不能有正负号。判断字符串是否符合上述模式时,首先尽可能多的扫描0~9的数位(有可能在起始处有‘+’或者‘-’),也就是前面模式中表示数值整数的A部分。如果遇到小数点’.‘,则开始扫描表示数值小数部分的B部分。如果遇到’e‘或者’E‘,则开始扫描表示数值指数的C部分。
整个代码的实现过程就是一个排除掉所有不满足数值条件的过程。1、判断string是否为空,如果为空,则返回false;2、定义三个布尔逻辑符:sign(’+‘或’-‘)、decimal(小数点’.‘)、hasE(指数符号e或E)为false;3、循环逐个检测字符串中的数值:(1)指数符号e或E:e的前后必须为整数,一个数值表示中只能有一个e或E;(2)小数点’.‘:只能出现一次,不能出现在最后一位,只能出现在e的前面;(3)'+'或’-‘号:第一次出现只能在第一个字符或者指数符号后,第二次出现只能在指数符号之后,不能出现在最后一位;(4)整数位:整数字符只能在’0‘~’9‘之间,不能是其他数据字符。不满足上述条件的返回false,否则返回true。
代码:
class Solution {
public:
bool isNumeric(char* string)
{
//把所满足非数值的条件都返回false,剩余的满足条件的都是true
if(string == nullptr)
return false;
bool sign = false, decimal =false, hasE = false;
for(int i=0;i < strlen(string); i++){
if(string[i] == 'e' || string[i] == 'E'){
//string[0]=e,即e的前面不为整数,返回false
if(i == 0) return false;
//string[strlen(string)-1]=e,即e为字符串最后一个,e的后面不为整数,返回false
if(i == strlen(string)-1) return false;
//一个数值表示中,只能有一个e
if(hasE) return false;
hasE = true;
}
else if(string[i] == '.'){
//小数点不能出现在e的后面
if(hasE || decimal) return false;
//如果出现在最后一位,返回false
if(i == strlen(string)-1) return false;
decimal = true;
}
else if(string[i] == '+' || string[i] == '-'){
//第一次出现只能在第一个字符或指数符号之后
if(!sign && i != 0 && !hasE) return false;
//第二次出现只能在指数符号之后
if(!hasE && sign) return false;
//’+‘和’-‘不能出现在最后一位,如果出现在最后一位,返回false
if(i == strlen(string)-1) return false;
sign = true;
}
else if(string[i] < '0' || string[i] > '9') return false;
}
return true;
}
};