public static boolean isNumber(String s) {
s = s.trim();
try {
Double.parseDouble(s);
}catch (NumberFormatException e){
return false;
}
// 排除特殊情况
char last = s.charAt(s.length()-1);
return (last >= '0' && last <= '9') || last == '.';
}
为了通过面试 当然不能这么写哈哈哈
思路是有限状态自动机!按照字符串从左到右的顺序,定义以下 9 种状态。
0.开始的空格
1.幂符号前的正负号
2.小数点前的数字
3.小数点、小数点后的数字
4.当小数点前为空格时,小数点、小数点后的数字
5.幂符号
6.幂符号后的正负号
7.幂符号后的数字
8.结尾的空格
理解透了 代码其实很简单
public static boolean isNumber(String s) {
// 主要就是把有限状态自动机画出来
Map[] states = {
new HashMap<Character, Integer>() {{ put(' ', 0); put('s', 1); put('d', 2); put('.', 4); }},
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); }}
};
// 标记当前状态
int p = 0;
// 用于数字、符号、幂符号转换
char t;
for (char c: s.toCharArray()){
if (c >= '0' && c <= '9'){
t = 'd';
}else if (c == '+' || c == '-'){
t = 's';
}else if (c == 'e' || c == 'E'){
t = 'e';
}
else if (c == '.' || c == ' '){
t = c;
}else {
t = '?';
}
if (!states[p].containsKey(t)){
return false;
}
p = (int) states[p].get(t);
}
// 合法的结束状态有 2, 3, 7, 8
return p == 2 || p == 3 || p == 7 || p == 8;
}
下面这个思路也太棒了吧 而且很好理解
public static 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++) {
//判定为数字,则标记numFlag
if (s.charAt(i) >= '0' && s.charAt(i) <= '9') {
numFlag = true;
//判定为. 需要没出现过.并且没出现过e
} else if (s.charAt(i) == '.' && !dotFlag && !eFlag) {
dotFlag = true;
//判定为e,需要没出现过e,并且出过数字了
} else if ((s.charAt(i) == 'e' || s.charAt(i) == 'E') && !eFlag && numFlag) {
eFlag = true;
numFlag = false;//为了避免123e这种请求,出现e之后就标志为false
//判定为+-符号,只能出现在第一位或者紧接e后面
} else if ((s.charAt(i) == '+' || s.charAt(i) == '-') && (i == 0 || s.charAt(i - 1) == 'e' || s.charAt(i - 1) == 'E')) {
//其他情况,都是非法的
} else {
return false;
}
}
return numFlag;
}