题目
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。
但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。
注意:
小数可以没有整数部分,例如.123等于0.123; 小数点后面可以没有数字,例如233.等于233.0;
小数点前面和后面可以有数字,例如233.666; 当e或E前面没有数字时,整个字符串不能表示数字,例如.e1、e1;
当e或E后面没有整数时,整个字符串不能表示数字,例如12e、12e+5.4;
样例: 输入: “0”输出: true
算法
(模拟,字符串处理) O(n)
-
先去除行首和行尾空格;
-
行首如果有一个正负号,直接忽略;
-
如果字符串为空或只有一个’.’,则不是一个合法数;
-
循环整个字符串,去掉以下几种情况:
(1) '.'或’e’多于1个;
(2) '.‘在’e’后面出现;
(3) ‘e’后面或前面为空,或者’e’前面紧跟着’.’;
(4) 'e’后面紧跟着正负号,但正负号后面为空; -
剩下的情况都合法;
时间复杂度分析:整个字符串只遍历一遍,所以时间复杂度是 O(n)。
class Solution {
public boolean isNumber(String s) {
int i = 0 ;
//去掉前后空格
while(i < s.length() && s.charAt(i) == ' ') i++;
int j = s.length() - 1;
while(j >= 0 && s.charAt(j) == ' ') j--;
if(i > j) return false;
s = s.substring(i,j + 1);
//忽略前面的减号加号点
if(s.charAt(0) == '+' || s.charAt(0) == '-')
s = s.substring(1);
//System.out.print(s);
if(s.isEmpty() || s.charAt(0) == '.' && s.length() == 1) return false;
int dot = 0,e = 0;
for(int k = 0;k < s.length();k++){
if(s.charAt(k) >= '0' && s.charAt(k) <= '9');
else if(s.charAt(k) == '.'){
dot++;
if(e > 0 || dot > 1) return false; //判别 123e56465.132 123.1232.123
}
else if(s.charAt(k) == 'e' || s.charAt(k) == 'E'){
e++;
//e1 1e .e 12e231e45
if(k == 0 || k + 1 == s.length() || e > 1 || s.charAt(k - 1) == '.' && k - 1 == 0 ) return false;
//System.out.print(k == 0 || k + 1 == s.length() || e > 1 || s.charAt(k - 1) == '.' && k - 1 == 0 );
if(s.charAt(k + 1) == '+' || s.charAt(k + 1) == '-'){ // 132e+
if(k + 2 == s.length())
return false;
//System.out.print(k + 2 == s.length() - 1);
else k++;
}
}
else{
return false;
}
}
return true;
}
}