原题链接:http://oj.leetcode.com/problems/valid-number/
Validate if a given string is numeric.
Some examples:"0"
=> true
" 0.1 "
=> true
"abc"
=> false
"1 a"
=> false
"2e10"
=> true
要求完成如下函数:
class Solution
{
public:
bool isNumber(const char *s)
{
}
}
解决方案:采用有穷自动机可以直观地描述所有可能的数字表达方式。
对于输入的字符串,按照输入在自动机上转换状态,待输入结束时到达可接受状态则为true,否则为false。
INVALID:%,&,$等无效输入,除过下面几种。
SPACE:空格
SIGN:符号+/-
DIGIT:数字0-9
DOT:点.
EXPONENT:指数符号e|E
(1):空格 数字 空格,如" 123 "
(2):空格 数字 点 数字 空格,如" 123.4 "
(3):空格 点 数字 空格,如" .123 "
(4):空格 正负号 数字 空格,如" +/-123 "
(5):空格 正负号 数字 点 数字 空格,如" +/-123.4 "
(6):空格 正负号 点 数字 空格,如" +/-.1234 "
(7):空格 {(1)|(2)|(3)|(4)|(5)|(6)}e|E{(1)|(4)} 空格,如" +/-123.4E123 "," .1234e+/-123 "
如上描述包含了所有的合法输入来表达数字,因此下一步就是用有穷自动机来描述着7种可能。
state 0:初始状态。
state 1:可接受状态,表示合法输入情况(1)(4)
state 2:接受点
state 3:接受正负号
state 4:接受点或者数字,可接受状态,表示合法输入情况(2)(5)
state 5:接受数字,可接受状态,表示合法输入情况(2)(3)(5)(6)
state 6:接受e|E
state 7:接受正负号
state 8:接受数字,可接受状态,表示合法输入情况(7)
state 9:接受空格,可接受状态,表示合法输入情况(1)(2)(3)(4)(5)(6)(7)
state -1:拒绝状态,表示非法输入
int transitionTable_9[][6]=
{
-1, 0, 3, 1, 2, -1, //state 0
-1, 9, -1, 1, 4, 6, //state 1
-1, -1, -1, 5, -1, -1, //state 2
-1, -1, -1, 1, 2, -1, //state 3
-1, 9, -1, 5, -1, 6, //state 4
-1, 9, -1, 5, -1, 6, //state 5
-1, -1, 7, 8, -1, -1, //state 6
-1, -1, -1, 8, -1, -1, //state 7
-1, 9, -1, 8, -1, -1, //state 8
-1, 9, -1, -1, -1, -1, //state 9
};
对输入的字符串逐个字符遍历,根据有穷自动机进行状态转移,若输入结束时到达可接受状态则为true,否则为false。如下代码:
class Solution
{
public:
bool isNumber(const char *s)
{
enum InputType
{
INVALID, // 0
SPACE, // 1
SIGN, // 2
DIGIT, // 3
DOT, // 4
EXPONENT, // 5
NUM_INPUTS // 6
};
int transitionTable_9[][NUM_INPUTS]=
{
-1, 0, 3, 1, 2, -1, //state 0
-1, 9, -1, 1, 4, 6, //state 1
-1, -1, -1, 5, -1, -1, //state 2
-1, -1, -1, 1, 2, -1, //state 3
-1, 9, -1, 5, -1, 6, //state 4
-1, 9, -1, 5, -1, 6, //state 5
-1, -1, 7, 8, -1, -1, //state 6
-1, -1, -1, 8, -1, -1, //state 7
-1, 9, -1, 8, -1, -1, //state 8
-1, 9, -1, -1, -1, -1, //state 9
};
int state = 0;
while (*s != '\0')
{
InputType inputType = INVALID;
if (isspace(*s))
inputType = SPACE;
else if (*s == '+' || *s == '-')
inputType = SIGN;
else if (isdigit(*s))
inputType = DIGIT;
else if (*s == '.')
inputType = DOT;
else if (*s == 'e' || *s == 'E')
inputType = EXPONENT;
state = transitionTable_9[state][inputType];
if (state == -1)
return false;
else
++s;
}
return state == 1 || state == 4 || state == 5 || state == 8 || state == 9;
}
};