面试题20:表示数值的字符串
2019-11-08 本文已影响0人
繁星追逐
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
- 例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。
- 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
使用正则表达式去匹配数字的模式:"[+-]?[0-9]([\.[0-9])?([Ee][+-]?[0-9]+)?"
代码如下:
public static boolean isNumeric(char[] str) {
if (str == null || str.length == 0) {
return false;
}
String s = String.valueOf(str);
//? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
//* 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
return s.matches("[+-]?[0-9]*(\\.[0-9]*)?([eE][+-]?[0-9]+)?");
}
思路二:
基本规则,小数点和E,e只能出现一次,小数点后必须有数字,E,e后必须是+-,并且后面必须有数字,否则剩下的字符必须是数字。
如果只有一位数字,判断是否是整数,不是返回false;设置两个标志位判断是否出现小数点或者E,e;然后遍历字符串,如果首位是+-,则判断是否是第一个字符,如果不是,并且前一个字符也不是E,e,则返回false;如果当前字符是Ee,则不可能是最后一位,并且之前没有出现过,不满足返回false,满足标志位改为Ee出现了。如果是小数点,只能出现一次,并且在E,e之前,满足条件小数点标志位改为出现。
最后的情况就是必须是数字。
一直没有跳出来,说明都满足,返回true。
代码如下:
/**
* @param str
* @return
*/
public static boolean isNumeric1(char[] str) {
if (str == null || str.length == 0) {
return false;
}
//长度只有1,必须在0-9之间
if (str.length == 1 && (str[0] < '0' || str[0] > '9')) {
return false;
}
boolean hasDot = false;
boolean hasE = false;
for (int i = 0; i < str.length; i++) {
//判断+-号的特殊情况
if (str[i] == '+' || str[i] == '-') {
//第二次出现正负号,前一个字符必须是E,e
if (i != 0 && str[i - 1] != 'E' && str[i - 1] != 'e') return false;
} else if (str[i] == 'E' || str[i] == 'e') {
//e:只有一个并且后面必须有数字==它不可能是最后一位
if (i == str.length - 1) return false;
if (hasE) return false;
hasE = true;
} else if (str[i] == '.') {
//只能出现一次,并且e和E以后不可能出现
if (hasDot || hasE) return false;
hasDot = true;
} else if (str[i] < '0' || str[i] > '9') {
//否则只能是数字
return false;
}
}
return true;
}
/**
* 剑指offer
分为A.B+C三部分去判断是否满足条件
*/
private int index = 0;
public boolean isNumeric3(char[] str) {
if (str.length < 1)
return false;
boolean flag = scanInteger(str);
if (index < str.length && str[index] == '.') {
index++;
flag = scanUnsignedInteger(str) || flag;
}
if (index < str.length && (str[index] == 'E' || str[index] == 'e')) {
index++;
flag = flag && scanInteger(str);
}
return flag && index == str.length;
}
private boolean scanInteger(char[] str) {
if (index < str.length && (str[index] == '+' || str[index] == '-') )
index++;
return scanUnsignedInteger(str);
}
private boolean scanUnsignedInteger(char[] str) {
int start = index;
while (index < str.length && str[index] >= '0' && str[index] <= '9')
index++;
return start < index; //是否存在整数
}