-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathq65_Valid_Number.py
More file actions
132 lines (117 loc) · 3.8 KB
/
q65_Valid_Number.py
File metadata and controls
132 lines (117 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import re
class Solution(object):
def isNumber(self, s):
"""
:type s: str
:rtype: bool
"""
#define DFA state transition tables
states = [{},
# State (1) - initial state (scan ahead thru blanks)
{'blank': 1, 'sign': 2, 'digit':3, '.':4},
# State (2) - found sign (expect digit/dot)
{'digit':3, '.':4},
# State (3) - digit consumer (loop until non-digit)
{'digit':3, '.':5, 'e':6, 'blank':9},
# State (4) - found dot (only a digit is valid)
{'digit':5},
# State (5) - after dot (expect digits, e, or end of valid input)
{'digit':5, 'e':6, 'blank':9},
# State (6) - found 'e' (only a sign or digit valid)
{'sign':7, 'digit':8},
# State (7) - sign after 'e' (only digit)
{'digit':8},
# State (8) - digit after 'e' (expect digits or end of valid input)
{'digit':8, 'blank':9},
# State (9) - Terminal state (fail if non-blank found)
{'blank':9}]
currentState = 1
for c in s:
# If char c is of a known class set it to the class name
if c in '0123456789':
c = 'digit'
elif c in ' \t\n':
c = 'blank'
elif c in '+-':
c = 'sign'
# If char/class is not in our state transition table it is invalid input
if c not in states[currentState]:
return False
# State transition
currentState = states[currentState][c]
# The only valid terminal states are end on digit, after dot, digit after e, or white space after valid input
if currentState not in [3,5,8,9]:
return False
return True
def isNumber1(self, s):
"""
:type s: str
:rtype: bool
"""
try:
float(s)
except:
return False
return True
def isNumber2(self, s):
"""
:type s: str
:rtype: bool
"""
if re.match("[\s\.+-]*\d+", s)==None:
return False
pattern = "\s*[+-]?\d*\.?\d*(e)?(?(1)[+-]?\d+\s*$|\s*$)"
return re.match(pattern, s)!=None
def isInteger(self, s):
if s:
if s[0] == '-' or s[0] == '+':
return self.isPureInteger(s[1:])
else:
return self.isPureInteger(s)
else:
return False
def isPureInteger(self, s):
if s:
for c in s:
if c not in set("0123456789"):
return False
return True
else:
return False
def isFloat(self, s):
if not s: return False
if s[0] == '-' or s[0] == '+':
s = s[1:]
if not s: return False
if s == '.': return False
pos_dot = -1
for (i, c) in enumerate(s):
if c in set("0123456789"):
pass
elif c == '.':
if pos_dot >= 0:
return False
else:
pos_dot = i
else:
return False
return True
def isNumber3(self, s):
"""
:type s: str
:rtype: bool
"""
s = s.strip().lower()
n = len(s)
if n == 0: return False
pos_e = -1
for (i, c) in enumerate(s):
if c == 'e':
if pos_e >= 0:
return False
else:
pos_e = i
if pos_e >= 0:
return self.isFloat(s[:pos_e]) and self.isInteger(s[pos_e + 1:])
else:
return self.isFloat(s)