验证给定的字符串是否为数字。
例如:
“0” => true
" 0.1 " => true
“abc” => false
“1 a” => false
“2e10” => true
说明: 我们有意将问题陈述地比较模糊。在实现代码之前,你应当事先思考所有可能的情况。
解题思路:
这道题的情况十分复杂,需要自己一个一个尝试某个形式算不算数字,也正因此,这道题斩获了做这么多题以来“最低赞/踩比”奖。不过貌似前几天把踩的数字给隐藏了,我记得当时是453个踩,16个赞…
宏观思路:
1 出现在字符串里的字符主要是这么几种情况:①数字 ②小数点 ③e ④正负号 ⑤其他字符
2 按顺序读取每个字符,根据每种字符出现的条件来判否,若最后未判否,则判定为数字
这道题的坑:
1 刚开始我做的时候,是根据已出现过的特殊字符(小数点和e)来做的,需要判断许多种情况;而正确(最快最简单的)思路是根据当前字符,判断可以判否的情况。
2 e只能出现一次,且前后必须都有数字
3 小数点只能出现一次,且不能在e后面
4 正负号可以出现在开头或者e的下一个字符
5 你看我这么描述可能很清楚,但是很容易把限制条件都放在一处进行判定,比如,1、2条可以这么说:e只能出现一次,前后必须有数字,且不能在小数点前面;小数点只能出现一次。 如果是这种思路,没办法做下去,因为无法判定后方的,很容易陷入对非边界特例的单独处理中。
收获:分析可能出现的情况,根据已出现的内容进行判定。
代码:
class Solution {
public boolean isNumber(String s) {
s = s.trim();
boolean eSeen = false;
boolean pointSeen = false;
boolean numSeen = false;
boolean numAfterESeen = true;
char[] str = s.toCharArray();
for(int i = 0;i < str.length;i++){
if (str[i] >= '0' && str[i] <= '9'){
numSeen = true;
numAfterESeen = true;
}
else if (str[i] == '.'){
if (pointSeen || eSeen)
return false;
pointSeen = true;
}
else if (str[i] == 'e'){
if (!numSeen || eSeen)
return false;
eSeen = true;
numAfterESeen = false;
}
else if (str[i] == '+' || str[i] == '-'){
if(i != 0 && str[i-1] != 'e')
return false;
}
else return false;
}
return numSeen && numAfterESeen;
}
}