请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串”+100″,”5e2″,”-123″,”3.1416″和”-1E-16″都表示数值。 但是”12e”,”1a3.14″,”1.2.3″,”+-5″和”12e+4.3″都不是。
这一题属于那种写起来超级多if-else
语句的题,做题的时候思路清晰至关重要。
- 数:基数和尾数组成
- 基数:(符号)小数或者整数
- E:
e
或者E
- 尾数:(符号位)整数
上面是数的结构,也是这题解答的一个比较好的思路:
- 首先检查基数部分,遇到
e
或者结束停止 - 如果第1步完成,检查尾数部分
注意点: 小数点最多只有一个,符号位可有可无,不能有非法字符,尾数为整数,尾数可有符号位
// 程序入口
public boolean isNumeric(char[] str) {
if(str.length == 0) return false;// 如果是空串
int i = isBase(str); // 判断基数部分
if(i == str.length)
return true; // 如果只有基数部分
else if(i == -1)
return false; // 基数部分不合法
else
return isInteger(str,i+1); // 判断尾数部分
}
// 判断基数部分是否合法
public int isBase(char[] cs){
int i = 0;
boolean dot = false; // 标记小数点
if(cs[i] == '+' || cs[i] == '-') i++; // 过滤标志位
while(i < cs.length){
if(dot == false && cs[i] == '.') dot =true; // 存在小数点
else if(dot == true && cs[i] == '.') return -1;// 存在多个小数点
else if(isE(cs[i])) return i; // 遇到了E结束
else if(!isNum(cs[i])) return -1; // 遇到非法字符
i++;
}
return i; // 只存在基数,且合法
}
// 判断尾数部分是否合法
public boolean isInteger(char[] cs,int i){
if(cs.length == i) return false; // 尾数为空,类似于123e,显然不合法
boolean flag = false; //
if(cs[i] == '+' || cs[i] == '-') i++; // 过滤符号位
while(i < cs.length){
if(isNum(cs[i++])) {
flag = true; // 有数值位
continue;
}
else return false;
}
return flag;
}
// 判断是否是数字符号
public boolean isNum(char c){
if(c >= '0' && c <= '9') return true;
else return false;
}
// 判断是否为字符e
public boolean isE(char e){
return e == 'e' || e == 'E';
}
上面的代码写起来还是有一些繁琐的,在笔试过程中,我们可以使用正则表达式
public boolean isNumeric(char[] str) {
String s=String.valueOf(str);
return s.matches("[+-]?[0-9]*(\\.[0-9]*)?([eE][+-]?[0-9]+)?");
}
\\.
引号内要双写\\
表示一个反\
,\\.
表示一个小数点,如果\.
则表示任意符号
正则表达式相关的知识参考Java正则表达式总结