Valid Number
Validate if a given string is numeric.
Some examples:
"0"
=> true
" 0.1 "
=> true
"abc"
=> false
"1 a"
=> false
"2e10"
=> true
Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.
思路:
状态机而已。不过略微有点复杂。当然也可以用正则来做。正则表达式:
FP_REGEX = / +[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)? +/
不过LeetCode不准用,所以这里借用JSON网站上对数的定义:
题解:
class Solution {
public:
enum State : int
{
TERM = 0,
SIGN = (1 << 0),
NUMBER = (1 << 1),
POINT = (1 << 2),
EXPSGN = (1 << 3),
BLANK = (1 << 8),
INVALID = -1
};
State currentCharState (char ch)
{
switch (ch)
{
case '+':
case '-':
return SIGN;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return NUMBER;
case '.':
return POINT;
case 'E':
case 'e':
return EXPSGN;
case ' ':
return BLANK;
case 0:
return TERM;
default:
return INVALID;
}
}
enum States : int
{
S0 = SIGN | NUMBER | POINT | BLANK,
S1 = NUMBER | POINT,
S2 = NUMBER | POINT | EXPSGN | BLANK | TERM,
S3A = NUMBER,
S3 = NUMBER | EXPSGN | BLANK | TERM,
S4 = SIGN | NUMBER,
S5 = NUMBER,
S6 = NUMBER | BLANK | TERM,
S7 = BLANK | TERM,
S8 = TERM
};
map<States, map<State, States>> STATE_MACHINE =
{
{S0, {{SIGN, S1}, {NUMBER, S2}, {POINT, S3A}, {BLANK, S0}}},
{S1, {{NUMBER, S2}, {POINT, S3A}}},
{S2, {{NUMBER, S2}, {POINT, S3}, {EXPSGN, S4}, {BLANK, S7}, {TERM, S8}}},
{S3A, {{NUMBER, S3}}},
{S3, {{NUMBER, S3}, {EXPSGN, S4}, {BLANK, S7}, {TERM, S8}}},
{S4, {{SIGN, S5}, {NUMBER, S6}}},
{S5, {{NUMBER, S6}}},
{S6, {{NUMBER, S6}, {BLANK, S7}, {TERM, S8}}},
{S7, {{BLANK, S7}, {TERM, S8}}},
{S8, {{TERM, S8}}}
};
bool isNumber (const char* s)
{
if (s == nullptr)
return false;
States stat = S0;
for (;;)
{
char ch = *s++;
State ch_stat = currentCharState (ch);
auto next_stat_iter = STATE_MACHINE[stat].find (ch_stat);
if (ch_stat == INVALID || next_stat_iter == STATE_MACHINE[stat].end())
break;
stat = next_stat_iter->second;
}
return (stat == S8);
}
};