题目:输入一个字符串(可能有空格,’.’,’e/E’),判断它是不是一个合法的数。
public boolean isNumber(String s)
思路:
-
用index来访问String。并写scanInteger和scanUnsignedInteger来辅助判断,返回boolean。(scanInteger用来判断符号,然后判断数字再调用scanUnsignedInteger来做。扫描无符号函数时先记下原来的下标,如果最后的下标往后移动了,那就返回true)。
-
然后根据数字格式(X.XeX)来判断,’.’前面调用方法scanInteger返回结果①。’.’后面(如果有’.’的话)调用方法scanUnsignedInteger返回结果②。①和②只要有一个为true就行(像1.和.16),①和②||起来结果记为③。’e’后面(如果有’e’的话)调用方法scanInteger返回结果④。③和④需要都为true才行(.e不行)。③和④&&起来得到结果⑤。
-
最后注意需要index走到string的最后才能行(用来处理0.16+这种情况,index走到+,但是返回了true)。
-
注意:测试用例有加空格的情况,所以用前先s.trim()然后再去弄。
public class JudgeStringIsNumberOrNot {
private int index = 0;
public boolean isNumber(String s){
if(s == null || s.length() == 0){
return false;
}
//测试用例里带有空格,所以要trim
s = s.trim();
//根据数字格式作逻辑判断 格式:X.XeX
//先扫'.'左边,结果记为(1)
boolean flag = scanInteger(s);
//到达'.'(如果有的话)
if(index < s.length() && s.charAt(index) == '.'){
index++;
//扫'.'后面,结果记为(2)。(1)和(2)只要有一个为true就行(比如1.,或.16,都可以)
//这边结果记为(3)
flag = scanUnsignedInteger(s) || flag;
}
//到达'e'(如果有的话)
if(index < s.length() && (s.charAt(index) == 'e' || s.charAt(index) == 'E')){
index++;
//扫'e'的右边,结果记为(4)。(3)和(4)都需要为true
flag = scanInteger(s) && flag;
}
//注意:最后index需要到s的最后,用来处理像0.16+这样的(最后index指向+号,但是返回true)
return flag && index == s.length();
}
//用来处理符号,检验数字部分直接用scanUnsignedInteger部分
public boolean scanInteger(String s){
//'+','-'通常就一个,所以可以用if
if(index < s.length() && (s.charAt(index) == '+' || s.charAt(index) == '-')){
index++;
}
return scanUnsignedInteger(s);
}
//用来扫描数字,返回true表示扫描到了数字(记录开始时的下标和最后的下标)
public boolean scanUnsignedInteger(String s) {
int start = index;
while(index < s.length() && (s.charAt(index) >= '0' && s.charAt(index) <= '9')){
index++;
}
//index往后移说明扫描到数字了。
return start < index;
}
public static void main(String[] args) {
JudgeStringIsNumberOrNot obj = new JudgeStringIsNumberOrNot();
System.out.println(obj.isNumber("1 "));
}
}