leetcode 65. Valid Number (合法的浮点数)
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.
Simple Solution
- 直接扫描判断
Java
class Solution {
public boolean isNumber(String s) {
int n=s.length();
int i=0;
while(i<n&&s.charAt(i)==' ')i++;
if(i<n&&(s.charAt(i)=='+'||s.charAt(i)=='-'))i++;
int num=0,pt=0;
while(i<n&&((s.charAt(i)>='0'&&s.charAt(i)<='9')||s.charAt(i)=='.')){
if(s.charAt(i)=='.')pt++;
else num++;
i++;
}
if(num<1||pt>1)return false;
if(i<n&&s.charAt(i)=='e'){
i++;
if(i<n&&(s.charAt(i)=='+'||s.charAt(i)=='-'))i++;
num=0;
while(i<n&&Character.isDigit(s.charAt(i))){
i++;
num++;
}
if(num<1)return false;
}
while(i<n&&Character.isSpace(s.charAt(i)))i++;
return i==n;
}
}
C++
class Solution {
public:
bool isNumber(string s) {
int n=s.length();
int i=0;
while(i<n&&isspace(s[i]))i++;
if(s[i]=='+'||s[i]=='-')i++;
int num=0,pt=0;
while(i<n&&(s[i]=='.'||isdigit(s[i]))){
s[i]=='.'?pt++:num++;i++;
}
if(num<1||pt>1)return false;
if(s[i]=='e'){
i++;
if(s[i]=='+'||s[i]=='-')i++;
int num=0;
while(i<n&&isdigit(s[i]))i++,num++;
if(num<1)return false;
}
while(i<n&&isspace(s[i]))i++;
return i==n;
}
};
Python
class Solution:
def isNumber(self, s: str) -> bool:
n=len(s)
i=0
while i<n and s[i]==' ':
i+=1
if i<n and (s[i]=='+' or s[i]=='-'):
i+=1
num,pt=0,0
while i<n and (s[i].isdigit() or s[i]=='.'):
if s[i]=='.':
pt+=1
else:
num+=1
i+=1
if pt>1 or num<1:
return False
if i<n and s[i]=='e':
i+=1
if i<n and (s[i]=='+' or s[i]=='-'):
i+=1
num=0
while i<n and s[i].isdigit():
i+=1
num+=1
if num<1:
return False
while i<n and s[i].isspace():
i+=1
return i==n
Go
func isNumber(s string) bool {
t:=strings.TrimSpace(s)
i,n:=0,len(t)
if i<n && (t[i]=='+'||t[i]=='-') {
i++
}
num,pt:=0,0
for i<n && (t[i]=='.' || isDigit(t[i])) {
if t[i]=='.' {
pt++
} else {
num++
}
i++
}
if num<1 || pt>1 {
return false
}
if i<n && t[i]=='e' {
i++
if i<n && (t[i]=='+'||t[i]=='-') {
i++
}
num=0
for i<n && isDigit(t[i]) {
i++;
num++;
}
if num<1 {
return false;
}
}
return i==n
}
func isDigit(b byte) bool {
return b>='0' && b<='9'
}
正则表达式
Java
class Solution {
public boolean isNumber(String s) {
return s.trim().matches("[+-]?(\\d+\\.?|\\.\\d+)\\d*(e[+-]?\\d+)?");
}
}
Python
class Solution:
def isNumber(self, s: str) -> bool:
m=re.compile(r"^[+-]?((\d+\.?\d*)|(\d*\.?\d+))(e[+-]?\d+)?$")
return m.match(s.strip(" "))
- 一些投机取巧的做法:
class Solution:
def isNumber(self, s: str) -> bool:
s=s.strip()
try:
float(s)
except ValueError:
return False
return True
DFA (Deterministic Finite Automata)
Python
class Solution:
def isNumber(self, s: str) -> bool:
states = [{},
{'blank':1,'sign':2,'digit':3,'.':4}, # state 1: initial
{'digit':3,'.':4}, # state 2: found sign
{'digit':3,'.':5,'e':6,'blank':9}, # state 3: digit consumer
{'digit':5}, # state 4: found dot (only a digit is valid)
{'digit':5,'e':6,'blank':9}, # state 5: after dot
{'sign':7,'digit':8}, # state 6: found 'e'
{'digit':8}, # state 7: sign after 'e' (only digit)
{'digit':8,'blank':9}, # state 8: digit after 'e' (digits or end)
{'blank':9}] # state 9: terminal
cur = 1
for c in s:
if c in '0123456789':
c = 'digit'
elif c in ' \t\n':
c = 'blank'
elif c in '+-':
c = 'sign'
if c not in states[cur]:
return False
cur = states[cur][c]
# valid end states: end on digit, after dot, digit after e, white space after valid input
if cur not in [3,5,8,9]:
return False
return True