题目
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、“5e2”、"-123"、“3.1416”、"-1E-16"、“0123"都表示数值,但"12e”、“1a3.14”、“1.2.3”、"±5"及"12e+5.4"都不是。
解题
解法1:枚举状态
主要思路:采用常规思路来解决,即枚举出符合规范的情况,然后一一判断。
- ‘.’ 只能出现一次,并且要早于‘E’或者‘e’;
- ‘e’ 或者 ‘E’不能出现在开头,前面必须要有数字,后面也必须要有数字;
- ‘+’ ‘-’要么出现在头部,要么紧跟‘E’或者’e’;
时间复杂度:O(N) - N表示字符串的长度
空间复杂度:O(N) - N表示字符串的长度
public boolean isNumber(String s) {
if (s == null || s.length() == 0) return false;
s = s.trim();
boolean numFlag = false;
boolean dotFlag = false;
boolean eFlag = false ;
for (int i = 0; i < s.length(); i++ ) {
char temp = s.charAt(i);
if (temp >= '0' && temp <= '9') {
numFlag = true;
} else if (temp == '.' && !dotFlag && !eFlag) {
dotFlag = true;
} else if ((temp == 'e' || temp == 'E') && !eFlag && numFlag) {
eFlag = true;
numFlag = false;
} else if ((temp == '+' || temp == '-') && (i == 0 || s.charAt(i-1) == 'e' || s.charAt(i-1) == 'E')) {
} else {
return false;
}
}
return numFlag;
}
解法2:自动机
主要思路:自动机
时间复杂度:O(N) - N表示字符串的长度
空间复杂度:O(N) - N表示字符串的长度
public boolean isNumber(String s) {
Map[] states = {
new HashMap<Character, Integer>() {{put(' ', 0); put('d', 2); put('.', 4);put('s', 1);}},
new HashMap<Character, Integer>() {{put('d', 2); put('.', 4);}},
new HashMap<Character, Integer>() {{put('d', 2); put('.', 3); put('e', 5);put(' ', 8);}},
new HashMap<Character, Integer>() {{put('d', 3); put('e', 5); put(' ', 8);}},
new HashMap<Character, Integer>() {{put('d', 3);}},
new HashMap<Character, Integer>() {{put('s', 6); put('d', 7);}},
new HashMap<Character, Integer>() {{put('d', 7);}},
new HashMap<Character, Integer>() {{put('d', 7); put(' ', 8);}},
new HashMap<Character, Integer>() {{ put(' ', 8);}},
};
char t;
int p = 0;
char[] sChar = s.toCharArray();
for (char temp : sChar) {
if ( temp >= '0' && temp <= '9') t = 'd';
else if (temp == '+' || temp == '-') t = 's';
else if (temp == 'E' || temp == 'e') t = 'e';
else if (temp == '.' || temp == ' ') t = temp;
else t = '?';
if (!states[p].containsKey(t)) {
return false;
}
p = (int)states[p].get(t);
}
return p == 2 || p == 3 || p == 7 || p == 8;
}