最清晰的方法是有限元自动机,继续盗一下K大的图。

45FNAd

然后用dict / hashmap把状态转移用键值对表达出来即可。字符串读入成字符数组,遍历字符元素匹配空格、正负号、数字、e以及小数点进行状态转移,如果不存在则直接返回false。遍历结束后如果停留在:空格、(连续或前面为小数点或空格或e的)数字、前面有数字的小数点,则符合规则返回true。

(我自己脑补的状态序列,所以序号和图上有一点出入)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
public boolean isNumber(String s) {
Map[] states = {
new HashMap<>() {{put(' ', 0); put('s', 1); put('d', 2); put('.', 3);}},
new HashMap<>() {{put('d', 2); put('.', 3);}},
new HashMap<>() {{put('d', 2); put('.', 4); put('e', 5); put(' ', 8);}},
new HashMap<>() {{put('d', 4);}},
new HashMap<>() {{put('d', 4); put('e', 5); put(' ', 8);}},
new HashMap<>() {{put('d', 6); put('s', 7);}},
new HashMap<>() {{put('d', 6); put(' ', 8);}},
new HashMap<>() {{put('d', 6);}},
new HashMap<>() {{put(' ', 8);}}
};
int state = 0;
char token;
for(char ch : s.toCharArray()) {
if(ch >= '0' && ch <= '9') token = 'd';
else if(ch == '+' || ch == '-') token = 's';
else if(ch == '.' || ch == ' ') token = ch;
else if(ch == 'e' || ch == 'E') token = 'e';
else token = 'u';
if(!states[state].containsKey(token)) return false;
state = (int)states[state].get(token);
}
return (state == 2 || state == 4 || state == 6 || state == 8);
}
}