剑指 Offer 20. 表示数值的字符串
class Solution {
public boolean isNumber(String s) {
boolean isNum = false, isDot = false, isE = false; // 标记是否遇到数位、小数点、'e'或'E'
char[] ch = s.trim().toCharArray(); // 删除字符串头尾的空格,转为字符数组,方便遍历判断每个字符
for(int i = 0; i < ch.length; i++){
char c = ch[i];
if(c >= '0' && c <= '9') isNum = true; // 判断当前字符是否为 0~9 的数位
else if(c == '.'){
if(isDot || isE) return false; // 小数点之前可以没有整数,但是不能重复出现小数点、或出现'e'或'E'
isDot = true; // 标记已经遇到小数点
}else if(c == 'e' || c == 'E'){ // 遇到'e'或'E'
if(isE || !isNum) return false; // 'e'或'E'前面必须有整数,且前面不能重复出现'e'或'E'
isE = true; // 标记已经遇到'e'或'E'
isNum = false; // 重置isNum,因为'e'或'E'之后也必须接上整数,防止出现 123e或者123e+的非法情况
}else if(c == '-' || c =='+'){
if(i != 0 && ch[i - 1] != 'e' && ch[i - 1] != 'E') return false; // 正负号只可能出现在第一个位置,或者出现在'e'或'E'的后面一个位置
}else return false; // 其它情况均为不合法字符
}
return isNum; // 最后返回是否是数字
}
}
class Solution {
HashMap<Character, Integer>[] map = new HashMap[10];
void init(){
map[0] = new HashMap<Character, Integer>();
map[0].put(' ', 0);
map[0].put('s', 1);
map[0].put('d', 2);
map[0].put('.', 9);
map[1] = new HashMap<Character, Integer>();
map[1].put('d', 2);
map[1].put('.', 9);
map[2] = new HashMap<Character, Integer>();
map[2].put('d', 2);
map[2].put('.', 3);
map[2].put(' ', 8);
map[2].put('e', 5);
map[3] = new HashMap<Character, Integer>();
map[3].put('d', 4);
map[3].put(' ', 8);
map[3].put('e', 5);
map[4] = new HashMap<Character, Integer>();
map[4].put('d', 4);
map[4].put('e', 5);
map[4].put(' ', 8);
map[5] = new HashMap<Character, Integer>();
map[5].put('s', 6);
map[5].put('d', 7);
map[6] = new HashMap<Character, Integer>();
map[6].put('d', 7);
map[7] = new HashMap<Character, Integer>();
map[7].put('d', 7);
map[7].put(' ', 8);
map[8] = new HashMap<Character, Integer>();
map[8].put(' ', 8);
map[9] = new HashMap<Character, Integer>();
map[9].put('d', 4);
}
public boolean isNumber(String s) {
init();
int p = 0;
char t;
HashSet<Integer> end = new HashSet<>(Arrays.asList(2, 3, 4, 7, 8));
for(char c : s.toCharArray()){
if(c == ' '){
p = map[p].getOrDefault(c, -1);
}else if(c == '+' || c == '-'){
p = map[p].getOrDefault('s', -1);
}else if(c >= '0' && c <= '9'){
p = map[p].getOrDefault('d', -1);
}else if(c == 'e' || c == 'E'){
p = map[p].getOrDefault('e', -1);
}else if(c == '.'){
p = map[p].getOrDefault('.', -1);
}else return false;
if(p == -1) return false;
}
return end.contains(p);
}
}
简洁写法
class Solution {
public boolean isNumber(String s) {
Map[] states = {
new HashMap<>() {{ put(' ', 0); put('s', 1); put('d', 2); put('.', 4); }}, // 0.
new HashMap<>() {{ put('d', 2); put('.', 4); }}, // 1.
new HashMap<>() {{ put('d', 2); put('.', 3); put('e', 5); put(' ', 8); }}, // 2.
new HashMap<>() {{ put('d', 3); put('e', 5); put(' ', 8); }}, // 3.
new HashMap<>() {{ put('d', 3); }}, // 4.
new HashMap<>() {{ put('s', 6); put('d', 7); }}, // 5.
new HashMap<>() {{ put('d', 7); }}, // 6.
new HashMap<>() {{ put('d', 7); put(' ', 8); }}, // 7.
new HashMap<>() {{ put(' ', 8); }} // 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);
}
return p == 2 || p == 3 || p == 7 || p == 8;
}
}