题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
例如,字符串 “+100”,“5e2”,"-123",“3.1416” 和 “-1E-16” 都表示数值。但是 “12e”,“1a3.14”,“1.2.3”,“±5” 和 “12e+4.3” 都不是。
解题思路
非正则表达式解法
表示数值的字符串遵循模式A[.[B]][e|EC] 或者.B[e|EC] 。 其中A为数值的整数部分,B紧跟着小数点为数值的小数部分,C紧跟着’e’或者‘E’为数值的指数部分。在小数里可能没有数值的整数部分。例如,小数.123等于0.123。因此A部分不是必需的,如果一个数没有整数部分,那么它的小数部分不能为空。
上诉A和C都是可能以‘+’或者‘-’开头的0-9的数字串;B也是0-9的数位串,但前面不能有正负号。
判断一个字符串是否符合上述模式时,首先尽可能多地扫描0-9的数位(有可能在起始处有‘+’或者‘-’),也就是前面模式中表示数值的A部分,如果遇到小数点’.’,则开始扫描数值小数部分的B部分。如果遇到’e’或者‘E’,则开始扫描数值指数的C部分。
正则表达式解法
使用正则表达式进行匹配:
[] : 字符集合
() : 分组,在这里是为了让表达式更清晰
? : 重复 0 ~ 1 次
+ : 重复 1 ~ n 次
* : 重复 0 ~ n 次
. : 任意字符
\\. : 转义后的.
\\d : 任意数字
代码
非正则表达式解法
public class IsNumberic {
private static int i = 0;
public static boolean isNumberic(char[] str) {
if (str == null) {
return false;
}
boolean numberic = scanInteger(str);
if (i < str.length && str[i] == '.') {
i++;
numberic = numberic || scanUnsignedInteger(str);
}
if (i < str.length && (str[i] == 'e' || str[i] == 'E')) {
i++;
numberic = numberic && scanInteger(str);
}
return numberic && i == str.length;
}
public static boolean scanUnsignedInteger(char[] str) {
int before = i;
while (i < str.length && str[i] >= '0' && str[i] <= '9') {
i++;
}
return i > before;
}
public static boolean scanInteger(char[] str) {
if (i < str.length && (str[i] == '+' || str[i] == '-')) {
i++;
}
return scanUnsignedInteger(str);
}
public static void main(String[] args) {
String str = "+100";
System.out.println(isNumberic(str.toCharArray()));
i = 0;
str = "5e2";
System.out.println(isNumberic(str.toCharArray()));
i = 0;
str = "12e";
System.out.println(isNumberic(str.toCharArray()));
}
}
正则表达式解法
public class isNumberic_2 {
public static boolean isNumberic_2(String str) {
if (str == null || str.length() < 0) {
return false;
}
return new String(str).matches("[+-]?[\\d]*[\\.]?[\\d]*([eE][+-]?\\d+)?");
}
public static void main(String[] args) {
System.out.println(isNumberic_2("233."));
}
}
来自: 《剑指Offer》 Coding-Interviews/表示数值的字符串.md at master · todorex/Coding-Interviews
|