任务只有一句话判断输入的数字是否合法。说真的,看了给的十几个例子我又百度了一下才最终弄清规则。特别需要注意的是诸如+.5和90.这样的数一开始以为不合法,提交错误后才知道是可以的,小数点前或者后可以没有数字。首先只想到了各种ifelse无限嵌套,顿时索然无味一点都不想写,所以以下是百度看到思想后再写的。(以我的代码风格肯定也不会用enum,直接012345就完事了)
Validate if a given string can be interpreted as a decimal number.
Some examples:
"0"
=>true
" 0.1 "
=>true
"abc"
=>false
"1 a"
=>false
"2e10"
=>true
" -90e3 "
=>true
" 1e"
=>false
"e3"
=>false
" 6e-1"
=>true
" 99e2.5 "
=>false
"53.5e93"
=>true
" --6 "
=>false
"-+3"
=>false
"95a54e53"
=>false
还记得初学有限状态机好长时间都一知半解,最后终于恍然大悟,是个挺神奇的东西,于是后来考完试就没用过了,没成想在这里又遇上了。通过分析可以知道有6种可能的字符:非法输入(就是后五种之外的字符)、空格、正负号、小数点、数字、e/E。9种正确或者暂时不能判断是否正确的状态:(其中1478合法,其他暂时不能判断)
0、空格(只有空格,以下八种前面可以有任意数量空格)
1、数(不含小数点的数,可以含正负号)
2、点(可以含正负号)
3、正/负号(只有正负号)
4、点+数(在1基础上含小数点的数)
5、...+e/E(前面合法+e/E)
6、...+e/E+正/负号(前面合法+e/E+正负号)
7、...+e/E+数(此处的数同1,不能有小数点)
8、合法+空格(末尾可以有任意数量空格)
这9种情况似乎很复杂其实拿笔几分钟就推出来了,之间的转换关系,如果画图可能就是一张蜘蛛网,建议直接填二维数组,填完再对照以下代码:
class Solution {
public:
bool isNumber(string s) {
enum InputType {INVALID,SPACE,SIGN,DIGIT,DOT,EXPONENT};
int transTable[9][6] = {
{-1,0,3,1,2,-1},
{-1,8,-1,1,4,5},
{-1,-1,-1,4,-1,-1},
{-1,-1,-1,1,2,-1},
{-1,8,-1,4,-1,5},
{-1,-1,6,7,-1,-1},
{-1,-1,-1,7,-1,-1},
{-1,8,-1,7,-1,-1},
{-1,8,-1,-1,-1,-1}
};
int state = 0;
for (int i = 0;i < s.size();i++){
InputType input = INVALID;
if (s[i] == ' ') input = SPACE;
else if(s[i]=='+' || s[i]=='-') input = SIGN;
else if(isdigit(s[i])) input = DIGIT;
else if(s[i] == '.') input = DOT;
else if(s[i]=='e' || s[i]=='E') input = EXPONENT;
if ((state = transTable[state][input]) == -1)
return false;
}
return (state==1 || state==4 || state==7 || state==8);
}
};
此题也可以用正则表达式做,先去掉首尾空格然后去和正则表达式匹配,我就不具体解释了免得越说越乱,正则表达式的规则参考https://www.cnblogs.com/guozht/p/7610877.html。我补充一点,在C++中\d要写成双斜杠的\\d。代码超级简短,但是没有有限状态机舒服。
class Solution {
public:
bool isNumber(string s) {
s.erase(0,s.find_first_not_of(" "));
s.erase(s.find_last_not_of(" ") + 1);
if (s.empty()) return false;
string p = "[+-]?(\\d+\\.?|\\.\\d+)\\d*(e[+-]?\\d+)?";
return regex_match(s, regex(p));
}
};
最后有一点奇怪的是,正则表达式在LeetCode上耗时1504ms,几乎就要超时了,相比之下同样的方法java只用了38ms,不知是何缘故。