目前leetcode上AC率最低的一题。第一次实战有限状态机,终于摸到点皮毛了。
输入存在6种情况:
- 0 无效值 INVALID
- 1 空白符 SPACE
- 2 正负号 SIGN
- 3 小数点 DOT
- 4 数字 NUMBER
- 5 指数符 EXPONENT
通过在Custom Testcase输入测试用例,可以看出合法的格式,不一一列出。
状态跳转情况(英文表示该状态可以接受的输入,紧跟的数字表示将会跳转至哪个状态):
- 状态0:SPACE 0, SIGN 1, DOT 2, NUMBER 3
- 状态1:DOT 2, NUMBER 3
- 状态2:NUMBER 4
- 状态3(合法结束):DOT 4, NUMBER 3, EXPONENT 5, SPACE 8
- 状态4(合法结束):EXPONENT 5, NUMBER 4, SPACE 8
- 状态5:SIGN 6, NUMBER 7
- 状态6:NUMBER 7
- 状态7(合法结束):NUMBER 7, SPACE 8
- 状态8(合法结束):SPACE 8
代码使用到状态转移表,行号代表状态,列号代表当前输入情况,元素数值代表即将跳转至的状态。
bool isNumber(char* s) {
enum InputType
{
INVALID,
SPACE,
SIGN,
DOT,
NUMBER,
EXPONENT,
NUM_STATE,
};
int transTable[][NUM_STATE] =
{
-1, 0, 1, 2, 3, -1,
-1, -1, -1, 2, 3, -1,
-1, -1, -1, -1, 4, -1,
-1, 8, -1, 4, 3, 5,
-1, 8, -1, -1, 4, 5,
-1, -1, 6, -1, 7, -1,
-1, -1, -1, -1, 7, -1,
-1, 8, -1, -1, 7, -1,
-1, 8, -1, -1, -1, -1
};
int state = 0;
int inputType = 0;
while (*s != '\0')
{
if (isspace(*s))
inputType = SPACE;
else if (*s == '+' || *s == '-')
inputType = SIGN;
else if (*s == '.')
inputType = DOT;
else if (isdigit(*s))
inputType = NUMBER;
else if (*s == 'E' || *s == 'e')
inputType = EXPONENT;
else
inputType = INVALID;
state = transTable[state][inputType];
if (state == -1)
return false;
++s;
}
return state == 3 || state == 4 || state == 7 || state == 8;
}
Reference:https://github.com/fuwutu/LeetCode/blob/master/Valid%20Number.cpp