https://leetcode.com/problems/valid-number/
65. Valid Number
Total Accepted: 38767 Total Submissions: 328141 Difficulty: Hard
Validate if a given string is numeric.
Some examples:"0" => true" 0.1 " => true"abc" => false"1 a" => false"2e10" => true
Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.
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.
Code
class Solution(object):
def isNumber(self, s):
s = s.strip()
return self._isNumber(s, ["+", "-", "."], True, True)
def _isNumber(self, s, valid_first_chars = [], check_dot=True, check_e=True):
if not s: return False
if s.isdigit(): return True
if (not s[0] in map(str, range(10)) + valid_first_chars):
return False
if s[0] in valid_first_chars:
if (s[0] == "+" or s[0] == "-") and self._isNumber(s[1:], ["."], check_dot, check_e):
return True
if s[0] == "." and self._isNumber(s[1:], [], False, check_e):
return True
if check_e:
es = s.split("e")
if len(es) > 2: return False
if len(es)==2 and self._isNumber(es[0], ["+", "-", "."], True, False) \
and self._isNumber(es[1], ["+", "-"], False, False):
return True
if check_dot:
dots = s.split(".")
if len(dots) > 2: return False
if len(dots)==2 and self._isNumber(dots[0], ["+", "-"], False, False) \
and (self._isNumber(dots[1], [], False, False) or dots[1] == ''):
return True
return False
Idea
My (also most people’s) way is going straight to handle different cases for parsing numbers.
- The most trivial case: an empty string or a null variable can’t be a valid number (line 7)
- Use string.isdigit() to check if a string contains pure number (without ‘+’, ‘-‘, ‘.’ or ‘e’). (line 8)
- a valid number must start with 0~9 or “+”, “-” or “.” (line 10-11)
- if `s` starts with “+” or “-“, then `s[1:]` should be a valid number without prefix as “+” or “-“. However `s[1:]` can start with `.`, for example, “+.43” is a valid number (line 14-15)
- if `s` starts with “.”, then `s[1:]` should be a pure valid number without any possibility to have prefix such as “+”, “-” and “.” (line 16-17)
- if you want to check if `s` is in scientific notation, the part before “e” should be a valid number with at most one prefix (“+”, “-” or “.”). The part after `e` can’t start with “.” but can start with “+” or “-“. (line 22-24)
- if you want to check if `s` is in a float notation, the part before “.” should be a valid number without any dot in it. The part after “.” should not have any dot in it either. It should not have any sign (“+” or “-“) after “e”. (line 29-31)
Reference
An exhausted list of test case:
