解题思路:
1.在数值之前可能有一个表示正负的‘+’或者‘-’,接下来是若干个0到9的数位表示数值的整数部分(在某些小数里可能没有数值的整数部分)。如果数值是一个小数,那么在小数点后面可能会有若干个0到9的数位表示数值的小数部分。如果数值用科学技术法表示,接下来是一个’e’或者‘E’,以及紧跟着的一个整数(可以有正负号)表示指数。
2.判断一个字符串是否符合上述模式时,首先看第一个字符是不是正负号。如果是,在字符串上移动一个字符,继续扫描剩余的字符串中0-9的数位。如果是一个小数,则将遇到小数点。另外,如果是用科学计数法表示的数值,在整数或者小数的后面还可能遇到‘e’或者‘E’。编写代码时时刻需要判断数组是否越界。
public class Solution {
public boolean isNumeric(char[] str) {
if (str == null || str.length == 0) {
return false;
}
int index = 0;
// 如果第一位是正数或者负数
if (str[index] == '+' || str[index] == '-') {
index++;
}
// 如果此时达到数组的长度,证明此时字符数组为“+”,“-”
if (index == str.length) {
return false;
}
boolean isNumeric = true;
index = scanDigits(str, index);
// 扫描数字部分,扫完之后,index肯定指向非整数字符或者到达数组的末尾
if (index < str.length) {
// 继续扫描后面部分
if (str[index] == '.') {
// 如果此时index指向字符为小数点,则继续往后判断是否为小数位
// 从第index+1位开始继续扫描,直到扫到第一个非数字字符或者数组结尾
index++;
index = scanDigits(str, index);
if (index < str.length) {
// 未扫描到数组尾部,此时index指向第一个非数字字符,判断是否为指数部分的开头(e或者E)
if (str[index] == 'e' || str[index] == 'E') {
// 判断e和E之后的字符是否满足指数条件
index++;
if (index == str.length) {
// 此时类似于“123.46e”,不是数值
isNumeric = false;
} else {
// 在不越界的情况下判断是否为指数
// 此时加1后还得判断数组是否越界
isNumeric = isExponential(str, index);
}
} else {
// index所指字符为e,E之外的字符,肯定不是数值
isNumeric = false;
}
} else {
// 扫描到数组结尾,此时的数值类似“+123.456”
isNumeric = true;
}
} else if (str[index] == 'e' || str[index] == 'E') {
// 如果此时index指向字符为e或者E,则继续往后判断是否为指数位
index++;
if (index == str.length) {
// 此时类似于“123e”,不是数值
isNumeric = false;
} else {
// 在不越界的情况下判断是否为指数
// 此时加1后还得判断数组是否越界
isNumeric = isExponential(str, index);
}
} else {
// 如果此时index指向字符所指向字符为非上述字符,则该字符数组肯定不是数值
isNumeric = false;
}
} else {
// 已经扫描到字符串尾部,此时的字符串应为“234“
isNumeric = true;
}
return isNumeric;
}
// 扫描从e之后的字符是否是指数,题目中的指数部分不允许有小数
private boolean isExponential(char[] str, int index) {
// 此时index指向e之后的第一个字符,肯定不越界,至少是length前一个字符
if (str[index] == '+' || str[index] == '-') {
// 如果此时所指字符为+,-号.index后移一位
index++;
}
// 找到第一个非数字字符或者到达数组尾部则循环结束
while (index < str.length && str[index] >= '0' && str[index] <= '9') {
index++;
}
if (index == str.length) {
// 此时指数部分满足要求
return true;
} else {
return false;
}
}
private int scanDigits(char[] str, int index) {
while (index < str.length && str[index] >= '0' && str[index] <= '9') {
index++;
}
return index;
}