[LeetCode 65] Valid Number
题目
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
Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one. However, here is a list of characters that can be in a valid decimal number:
- Numbers 0-9
- Exponent - “e”
- Positive/negative sign - “+”/"-"
- Decimal point - “.”
Of course, the context of these characters also matters in the input.
Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button to reset your code definition.
思路
- 条件判断很多,如果采用if else需要写非常多的判断分支;并且每遍历一个字符都需要基于前面遍历过的信息来判断,可以将前面遍历的信息映射为一个状态(比如,是否为整数、double、带符号数等),每遍历一个字符都根据前一个状态来判断是否合法,并且可以得到新的状态。即通过状态机来简化判断逻辑;
- 状态机的三个要素:状态定义,输入条件,状态转移矩阵;需要定义的状态举例:(空字符开头)起始状态,整数状态、double数状态、科学计数状态等;输入条件:空字符、正负符号、数字、E/e、非法字符;状态转移矩阵为判断核心。基于前一状态,根据输入条件来判断当前状态是否成立,因为状态和输入条件都是有限的,所以矩阵可以提前计算好,以二维数组存放即可。这也算用空间换取判断逻辑的时间。
Code in C++
class Solution {
public:
bool isNumber(string s) {
int state[10][5] = {{0, 1, 2, -1, 4}, // begin or blank
{-1, -1, 2, -1, 4}, // sign before exponent
{-1, -1, -1, -1, 7}, // dot, no number before it
{-1, 9, -1, -1, 5}, // exponent
{8, -1, 6, 3, 4}, // number
{8, -1, -1, -1, 5}, // exponent number
{8, -1, -1, 3, 7}, // dot with number front
{8, -1, -1, 3, 7}, // number with dot front
{8, -1, -1, -1, -1}, // blank at end
{-1, -1, -1, -1, 5} // sign after exponet
};
int pre = 0, cur = 0, input;
for (int i = 0; i < s.size(); i++) {
pre = cur;
if (s[i] == ' ')
input = 0;
else if (s[i] == '+' || s[i] == '-')
input = 1;
else if (s[i] == '.')
input = 2;
else if (s[i] == 'E' || s[i] == 'e')
input = 3;
else if (s[i] >= '0' && s[i] <= '9')
input = 4;
else
input = -1;
if (input == -1 || (cur=state[pre][input]) == -1)
return false;
}
return cur > 3 && cur < 9;
}
};