题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、“5e2”、"-123"、“3.1416”、“0123"都表示数值,但"12e”、“1a3.14”、“1.2.3”、“±5”、"-1E-16"及"12e+5.4"都不是。
题解
这题的状态定义10种(幂符号为e或E):
- 开始的空格
- 幂符号前的正负号
- 小数点前的数字
- 小数点(前面不包含数字)
- 小数点(前面包含数字)
- 小数点后的数字
- 幂符号
- 幂符号后的正负号
- 幂符号后的数字
- 结尾的空格
状态的合法转换有(表中内容为转换条件):
起始/终止 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
1 | 空格 | 正负号 | 数字 | 小数点 | ||||||
2 | 数字 | 小数点 | ||||||||
3 | 数字 | 小数点 | e或E | 空格 | ||||||
4 | 数字 | |||||||||
5 | 数字 | e或E | 空格 | |||||||
6 | 数字 | e或E | 空格 | |||||||
7 | 正负号 | 数字 | ||||||||
8 | 数字 | |||||||||
9 | 数字 | 空格 | ||||||||
10 | 空格 |
最终的合法状态有:
- 状态3,如:
+10
,18
- 状态5,如:
-4.
- 状态6,如:
7.8
- 状态9,如:
+5e-3
,4e7
- 状态10,如:
3._
,-4.5e+7__
(下划线指空格!)
这题的输入字符有6种:
- 空格,记为1
- 加减符号,记为2
- 数值,记为3
- 小数点,记为4
- e或E,记为5
- 其他字符(不用记录,直接返回false)
代码实现:
class Solution {
public boolean isNumber(String s) {
int [][] states = new int[11][6];
// 状态0为前面的空格,状态1为正负符号
states[1][1] = 1; states[1][2] = 2; states[1][3] = 3; states[1][4] = 4;
states[2][3] = 3; states[2][4] = 4;
states[3][3] = 3; states[3][4] = 5; states[3][5] = 7; states[3][1] = 10;
states[4][3] = 5;
states[5][1] = 10; states[5][3] = 6; states[5][5] = 7;
states[6][1] = 10; states[6][3] = 6; states[6][5] = 7;
states[7][2] = 8; states[7][3] = 9;
states[8][3] = 9;
states[9][3] = 9; states[9][1] = 10;
states[10][1] = 10;
int state = 1;
for (int i = 0 ; i < s.length() ; i++)
{
char tmpChar = s.charAt(i);
int direction = 0;
if (tmpChar == ' ') {
direction = 1;
} else if (tmpChar == '+' || tmpChar == '-') {
direction = 2;
} else if (tmpChar <= '9' && tmpChar >= '0') {
direction = 3;
} else if (tmpChar == '.') {
direction = 4;
} else if (tmpChar == 'E' || tmpChar == 'e') {
direction = 5;
} else {
return false;
}
state = states[state][direction];
if (state == 0) {
return false;
}
}
return state == 3 || state == 5 || state == 6 || state == 9 || state == 10;
}
}
时间复杂度:
O
(
n
)
O(n)
O(n)。
只需遍历字符串一次即可。
空间复杂度:
O
(
1
)
O(1)
O(1)。
开的状态转换表是固定大小的。