题目:
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"-1E-16"、"0123"都表示数值,
但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。
思路:
面对情况较多并且前后顺序混乱的这种问题,
我们应该先抽象出合理数字的模型,再拆分问题进行解决;
举个例子:对于数字**-16.321E-16**可以说是这种情况下所有条件都加上了;
对这个数字进行拆分:【-16】【.】【321】【E/e】【-16】
可以看到,对于一个数字而言,最多有这5个部分,那么我们可以从向后拆解给出的字符串
①首先拆出最前面的第一部分数字,其是否合规标记为:OK1;
②拆解出①后,判断当前位置是否为 . ,如果是则走③,如果不是则走④
③拆解**.后面的数字,重复①的判断,注意不能有符号,而①可以有符号,合规与否标记为OK2
④拆解后面的数字,重复①的过程可以有符号**,合规与否标记为OK3
⑤判断当前指针位置是否为末尾,如果是则记录为OK4
最后判断逻辑:ret
当有**.** 的时候,前后必须有一个成立,也就是①和③必须成立一个:ret = OK1 || OK2
如果有e,则前面的ret与OK3必须同时成立:ret = ret && OK3
最后也必须满足后面没有奇奇怪怪的东西:ret&= OK4;
代码:
class Solution {
public:
bool isInt(string& s, int& i)
{
int i_before = i;
while(i < s.size() && s[i] >= '0' && s[i] <= '9'){
i++;
}
if(i_before < i)
return true;
else
return false;
}
bool isNumber(string s) {
if(s.size() == 0)
return false;
// 首先去除首末空格
s.erase(0,s.find_first_not_of(' '));
s.erase(s.find_last_not_of(' ')+1);
int i = 0;
if(s[i] == '+' || s[i] == '-'){
i++;
}
bool is_int = isInt(s, i);
bool ret = is_int;
if(i < s.size())
{
if(s[i] == '.'){
i++;
bool is_int2 = isInt(s,i);
ret = ret || is_int2;
}
if(i < s.size() && (s[i] == 'e' || s[i] == 'E') )
{
i++;
if(i < s.size()){
if(s[i] == '+' || s[i] == '-'){
i++;
}
bool is_int3 = isInt(s,i);
ret &= is_int3;
}
else
return false;
}
}
if(i == s.size() && ret){
return true;
}
else
return false;
}
};