这道题目的解法很多:
- 正则匹配
- Java类库
- 条件判断
- 有限状态机
我一开始想的解法是条件判断,后来对其进行了修改,使用了自上而下的递归:
import java.util.*;
public class Solution {
// 合法字符集, E视同e,因此不纳入该集合
private Set<Character> legalChars = new HashSet<>(Arrays.asList(
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'+', '-', '.', 'e'));
public boolean isNumeric (String str) {
if (str == null || str.length() == 0)
return false;
str = str.toLowerCase(); // E视同e,简化后续逻辑
char[] charArr = str.toCharArray();
if (hasIllegalChar(charArr) // 排除不合法的字符的影响
|| hasCharMoreThan(charArr, '.', 1) // .的个数不能超过1
|| hasCharMoreThan(charArr, 'e', 1)) { // e的个数不能超过1
return false;
}
// 开始递归的时候已经进行了筛检,剩下的字符串只有合法字符,至多一个'.',至多一个'e'
return doDudge(str);
}
// 递归辅助函数
private boolean doDudge(String str) {
if (str == null || str.length() == 0)
return false;
if (str.contains("e")) {
// 自上而下的递归,在开始递归前,确保'.'只能出现在'e'的左侧,且不能以'e'结尾
if (str.endsWith("e") || str.indexOf('.') > str.indexOf('e'))
return false;
return doDudge(str.split("e")[0]) && doDudge(str.split("e")[1]);
} else if (str.startsWith("+") || str.startsWith("-")) {
// 针对没有'e'或有'e'但是递归拆分下来的场景,确保开头最多出现一个'+'或'-'
if (str.length() == 1 || str.charAt(1) == '+' || str.charAt(1) == '-')
return false;
// 忽略开头的'+'或者'-',继续向后递归处理
return doDudge(str.substring(1));
} else {
// 递归剥离了'e'和开头的'+', '-',禁止还存在'+', '-',禁止以'.'结尾,其余均合法
return !str.endsWith(".") && !str.contains("+") && !str.contains("-");
}
}
// 辅助函数,判断一个数组中是否存在超过count个字符c
private boolean hasCharMoreThan(char[] arr, char c, int count) {
int cnt = 0;
for (char ch : arr) {
if (ch == c) {
++cnt;
}
}
if (cnt > count)
return true;
return false;
}
// 辅助函数,判断字符数组中是否存在合法字符以外的字符
private boolean hasIllegalChar(char[] arr) {
for (char c : arr) {
if (!legalChars.contains(c)) {
return true;
}
}
return false;
}
} 
京公网安备 11010502036488号