最清晰的方法是有限元自动机,继续盗一下K大的图。
然后用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); } }
|