一 题目
Validate if a given string can be interpreted as a decimal number.
Some examples:"0"
=> true
" 0.1 "
=> true
"abc"
=> false
"1 a"
=> false
"2e10"
=> true
" -90e3 "
=> true
" 1e"
=> false
"e3"
=> false
" 6e-1"
=> true
" 99e2.5 "
=> false
"53.5e93"
=> true
" --6 "
=> false
"-+3"
=> false
"95a54e53"
=> false
Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one. However, here is a list of characters that can be in a valid decimal number:
- Numbers 0-9
- Exponent - "e"
- Positive/negative sign - "+"/"-"
- Decimal point - "."
Of course, the context of these characters also matters in the input.
Update (2015-02-10):
The signature of the C++
function had been updated. If you still see your function signature accepts a const char *
argument, please click the reload button to reset your code definition.
Accepted 137,980 Submissions 958,120
二 分析
hard 级别,通过率很低啊、看样子不到15%。这个难不是算法的难,是各种变态的case让你调着就要疯的感觉。
我觉得跟之前的LeetCode 8. String to Integer (atoi) 各种判断类似的,属于考察细节换句话就是严谨性,耐心的。题目的case是不够的。我自己跑的代码的也不全,就是失败了有加上的。
1 题目本身是有些模糊的,大概根据case不断的去理解:除了数字之外, 空格‘ ’, 小数点 '.', 幂 'e/E', 还要加上正负号 '+/-", 除了这些字符需要考虑意外,出现了任何其他的字符,可以马上判定不是数字。下面我们来看下特殊字符:
1. 空格 ‘ ’: 预处理trim时去掉首尾空格,中间再检测到空格,则判定不是数字。
2. 小数点 '.':小数点需要分的情况较多,首先的是小数点只能出现一次,但是小数点可以出现在任何位置(注意.1是true) ,其次小数点不能出现在幂'e' 之后,如 "3e.1" false, "99e2.5" false。还有,当小数点位于末尾时,前面必须是数字,如 "1."。
3. 幂'e':需要出现在数字之间。如 "e" false, ".e1" false, "3.e" false, "3.e1" true。而且小数点只能出现在e之前,还有就是e前面不能是符号,如 "+e1" false, "1+e" false.
4. 正负号 '+/-",正负号可以再开头出现,可以再自然数e之后出现,但不能是最后一个字符,后面得有数字,如 "+1.e+5" true。
所以,不断的调试。先过了给出的case。提测了好几版才过。
public static void main(String[] args) {
System.out.println(" -.7e+0435"+"->"+ isNumber(" -.7e+0435"));
System.out.println(" 005047e+6"+"->"+ isNumber(" 005047e+6"));
System.out.println("+.8"+"->"+ isNumber("+.8"));
System.out.println(" 2e-9 "+"->"+ isNumber(" 2e-9 "));
System.out.println("-e10"+"->"+ isNumber("-e10"));
System.out.println("3.e1"+"->"+ isNumber("3.e1"));
System.out.println("3.e"+"->"+ isNumber("3.e"));
System.out.println(" -."+"->"+ isNumber(" -."));
System.out.println("4e+"+"->"+ isNumber("4e+"));
System.out.println("3-2"+"->"+ isNumber("3-2"));
System.out.println("6+1"+"->"+ isNumber("6+1"));
System.out.println(".e1"+"->"+ isNumber(".e1"));
System.out.println(".1"+"->"+ isNumber(".1"));
System.out.println("0"+"->"+ isNumber("0"));
System.out.println(" 0.1 "+"->"+ isNumber(" 0.1 "));
System.out.println("abc"+"->"+ isNumber("abc"));
System.out.println("1 a"+"->"+ isNumber("1 a"));
System.out.println("2e10"+"->"+ isNumber("2e10"));
System.out.println(" -90e3 "+"->"+ isNumber(" -90e3 "));
System.out.println(" 1e"+"->"+ isNumber(" 1e"));
System.out.println("e3"+"->"+ isNumber("e3"));
System.out.println(" 6e-1"+"->"+ isNumber(" 6e-1"));
System.out.println(" 99e2.5 "+"->"+ isNumber(" 99e2.5 "));
System.out.println("53.5e93"+"->"+ isNumber("53.5e93"));
System.out.println(" --6 "+"->"+ isNumber(" --6 "));
System.out.println("-+3"+"->"+ isNumber("-+3"));
System.out.println("95a54e53"+"->"+ isNumber("95a54e53"));
System.out.println(""+"->"+ isNumber(""));
System.out.println(""+"->"+ isNumber(""));
}
/**
* @author bohu83
* @param s
* @return
*/
public static boolean isNumber(String s) {
if(s== null || s.trim().equals("")){
return false;
}
s = s.trim();
boolean num = false;
boolean e = false;
boolean point = false;
for(int i=0;i<s.length();i++){
char c = s.charAt(i);
//非法字母排除
if((c <'0' || c >'9') && c!='e' && c!='+' && c!='-' && c!='.' ){
return false;
}
if(c>='0'&& c<='9'){
num =true;
}
//e只能出现一次。且在数字之间
else if(c=='e'){
e = true;
if(i==0 || i!= s.lastIndexOf("e")|| i==s.length()-1 || !num){
return false;
}
num =false;
}
else if(c=='+'|| c=='-'){//符号只能出现在首位或者e之后
if (i > 0 && s.charAt(i - 1) != 'e'){
return false;
}
}else if(c=='.'){//e之后不能有小数点,不能重复
if((e&&i>s.indexOf("e")) || point ){
return false;
}
point =true;
}
}
return num;
}
Runtime: 2 ms, faster than 76.80% of Java online submissions for Valid Number.
Memory Usage: 35.9 MB, less than 100.00% of Java online submissions for Valid Number.
时间复杂度O(N).