题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串
+100, 5e2, -123, 3.14e+1都表示数值,而12e, 1a3.12, 1.2.3, +-5都不是。
首先我们要明白数值的格式为 A.B[e|E]C,其中 A, B, C 代表的是数字,有一点不同的是 A, C 中的前方可以有正负号,而 B 不能有正负号。我们变成的思路便是,首先扫描字符串,看是否匹配 A,即字符串的前方是否是数字(可包含正负号),接着如果碰到小数点,则扫描小数点后的字符是否是数字(不能包含正负号);最后匹配科学计数法,如果碰到 e|E,那么扫描后面的字符是否是数字(可包含正负号)。
代码如下:
public class IsNumberic {// 全局变量,控制从哪里开始扫描字符串private static int index;public static boolean isNumberic(char[] str) {if (str == null) {return false;}// 扫描字符串开头是否是数字(可带正负号)boolean numberic = scanInteger(str, 0);if (index < str.length) {// 如果有小数点if (str[index] == '.') {index++;// 扫描小数点后的数字(不带正负号)// 使用 || 是因为 A. 或者 .B都算有效的数值numberic = scanUnsignedInteger(str, index) || numberic;}}if (index < str.length) {// 如果扫描到 e|Eif (str[index] == 'e' || str[index] == 'E') {index++;// 扫描 e|E 字符后面是否为数字(可带正负号)numberic = numberic && scanInteger(str, index);}}// 符合A.B[e|E]C的形式,并且字符串全部扫描完毕return numberic && index == str.length;}// 判断从某个位置开始,后面是否有数字(可带正负号)private static boolean scanInteger(char[] str, int start) {if (start >= str.length) {return false;}if (str[start] == '+' || str[start] == '-') {return scanUnsignedInteger(str, start + 1);}return scanUnsignedInteger(str, start);}// 判断从某个位置开始,后面是否有数字(不带正负号)private static boolean scanUnsignedInteger(char[] str, int start) {index = start;if (index < str.length) {while(str[index] >= '0' && str[index] <= '9') {index++;if (index == str.length) {break;}}}return index > start;}public static void main(String[] args) {System.out.println(isNumberic(".123".toCharArray())); // trueSystem.out.println(isNumberic("123.".toCharArray())); // trueSystem.out.println(isNumberic("+.123".toCharArray())); // trueSystem.out.println(isNumberic("-.123".toCharArray())); // trueSystem.out.println(isNumberic(".123e-2".toCharArray())); // trueSystem.out.println(isNumberic("1.2.2".toCharArray())); // falseSystem.out.println(isNumberic("1.2e+2".toCharArray())); // true}}
