1. 题目
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
若干空格
一个 小数 或者 整数
(可选)一个 ‘e’ 或 ‘E’ ,后面跟着一个 整数
若干空格
小数(按顺序)可以分成以下几个部分:
(可选)一个符号字符(’+’ 或 ‘-’)
下述格式之一:
至少一位数字,后面跟着一个点 ‘.’
至少一位数字,后面跟着一个点 ‘.’ ,后面再跟着至少一位数字
一个点 ‘.’ ,后面跟着至少一位数字
整数(按顺序)可以分成以下几个部分:
(可选)一个符号字符(’+’ 或 ‘-’)
至少一位数字
部分数值列举如下:
["+100", “5e2”, “-123”, “3.1416”, “-1E-16”, “0123”]
部分非数值列举如下:
[“12e”, “1a3.14”, “1.2.3”, “±5”, “12e+5.4”]
2. 题解
2.1 解法1: 通俗解法
- 使用 三个bool变量分别代表当前位置的前面的状态 是否有 数字, 点, e, 这个前面不单指前一个字符, 可能是已经遍历的前面整个字符串
- 遍历字符数组的所有字符, 排除各种不是数值的情况
注意:
- 在遍历开始前要去除字符串前后的空格
- 在每个条件判断时, 都需要再判断排除错误情况, 可以先列举进入该状态需要满足的条件然后取反来排除\
class Solution {
public boolean isNumber(String s) {
if (s == null || s.length() == 0) {
return false;
}
char[] ss = s.trim().toCharArray();
boolean hasNum = false, hasDot = false, hasEe = false;
for (int i = 0; i < ss.length; i++) {
if (ss[i] >= '0' && ss[i] <= '9') {
hasNum = true;
} else if (ss[i] == '.') {
// 需满足条件, 前面无点 且 无e
if (hasDot || hasEe) {
return false;
}
hasDot = true;
} else if (ss[i] == 'e' || ss[i] == 'E') {
// 需满足条件: 前面有数字且无e
if (hasEe || !hasNum) {
return false;
}
hasEe = true;
// 因为 e 后面需要跟数字, 排除123e或者123e+的情况,确保e之后也出现数
hasNum = false;
} else if (ss[i] == '+' || ss[i] == '-') {
// 需满足条件, 为首元素或前一个元素为 e ,设计其反面
if (i != 0 && ss[i - 1] != 'E' && ss[i - 1] != 'e') {
return false;
}
} else {
return false;
}
}
return hasNum;
}
}
参考: Java版本题解,逻辑清晰。