Today’s challenge look simple, but there are some cases that makes it a bit difficult.
Problem description
Given a string s
, return whether s
is a valid number.
For example, all the following are valid numbers: 2, 0089, -0.1, +3.14, 4., -.9, 2e10, -90E3, 3e+7, +6e-1, 53.5e93, -123.456e789
, while the following are not valid numbers: abc, 1a, 1e, e3, 99e2.5, --6, -+3, 95a54e53
.
Formally, a valid number is defined using one of the following definitions:
- An integer number followed by an optional exponent.
- A decimal number followed by an optional exponent.
An integer number is defined with an optional sign ’-’ or ’+’ followed by digits.
A decimal number is defined with an optional sign ’-’ or ’+’ followed by one of the following definitions:
- Digits followed by a dot ’.‘.
- Digits followed by a dot ’.’ followed by digits.
- A dot ’.’ followed by digits.
An exponent is defined with an exponent notation ‘e’ or ‘E’ followed by an integer number.
The digits are defined as one or more digits.
Examples
Input:
s = "0"
Output:
true
Input:
s = "e"
Output:
false
You can find a brief description about the problem here.
Experience
My first intuition was to type cast the number to float. If the number casts to float without any problem, then it is valid. If not, it is invalid. This intuition doesn’t work for the cases like “inf” and “NaN”s.
Then I tried checking the string whether it contains all letters, “-inf” will disqualify this check as well.
The reason I don’t want to use regular expression at first was to make my algorithm run faster but I ended up using it after all the failed trails. The regular expressions won’t work alone either; “0e” kind of value gives unwanted result. So, I combined the regular expressions with my previous intuitions.
The results
- Runtime: 34 ms, faster than 95.67% of SQL online submissions.
- Memory Usage: 13.9 MB, less than 75.31% of SQL online submissions.
The code
def isNumber(self, s: str) -> bool:
if re.match("[+-]?(d+([.]d*)?([eE][+-]?d+)?|[.]d+([eE][+-]?d+)?)", s):
try:
float(s)
return True
except ValueError:
return False
return False