[M]O-20 表示数值的字符串
问题描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、“5e2”、"-123"、“3.1416”、"-1E-16"、“0123"都表示数值,但"12e”、“1a3.14”、“1.2.3”、"±5"及"12e+5.4"都不是。
#本题有一些注意的情况
’1 ‘’ 1‘ 像这种前后有空格的都属于TRUE
’1. 1‘中间有空格属于FALSE
'.2' TRUE 小数点前可没有数字,但是后边必须有
问题分析
在 C++ 文档 中,描述了一个合法的数值字符串应当具有的格式。具体而言,它包含以下部分:
- 符号位,即 +、− 两种符号
- 整数部分,即由若干字符 0-9 组成的字符串
- 小数点
- 小数部分,其构成与整数部分相同
- 指数部分,其中包含开头的字符 e(大写小写均可)、可选的符号位,和整数部分
本题还有一点额外的不同,即允许字符串首末两端有一些额外的空格。
在上面描述的五个部分中,每个部分都不是必需的,但也受一些额外规则的制约,如:
- 如果符号位(±)存在,其后面必须跟着数字或小数点。
- 小数点的前后两侧,至少有一侧是数字。
自己方法——易理解的思路
(1)利用s.strip()
:删除字符串首尾的空格。转换字符串为列表。
(2)设置判断数字,小数点,指数e/E的标志。初始均为False.
(3)遍历列表
(4)如果遇到数字,则设置is_num为True
(5)如果遇到小数点,
- 不可能连续出现两个小数点
- 小数点之前不可能已经出现E/e
所以,上述两个条件满足一个即return False
否则,置is_dot=True
(6)如果遇到e/E,
- 前面必须有数字 not is_num
- 不可能已经出现E/e is_eorE
所以,上述两个条件满足一个即return False
否则,置is_eorE=True,且重置数字为False,因为e/E后面还必须有数字。
(例如1e
(应该是False),最后应该到return isnum这一步,由于在判断e时候已经把isnum变为False,所以此时最后结果为False对的,如果不加这一条件,可能会因为前面第一个数字已经把isnum变成True而让最终结果错误)
(7)如果遇到**±**,正负号之可能出现在两种情况下:
- 在首位
- 在e/E后面
如果上述情况都不满足,那一定return False
(8)遇到其他除了上面几种情况的字符 一律return False
(9)最后的return isnum
class Solution:
def isNumber(self, s: str) -> bool:
s=s.strip()
l=list(s)
is_num,is_dot,is_eorE=False,False,False
for i in range(len(l)):
if(l[i]>='0' and l[i]<='9'): is_num=True
elif(l[i]=='.'):
if (is_dot or is_eorE): return False
is_dot=True
elif(l[i]=='e' or l[i]=='E'):
if (not is_num or is_eorE): return False
else:
is_eorE=True
is_num=False
elif(l[i]=='+' or l[i]=='-'):
if(i!=0 and l[i-1]!='e'and l[i-1]!='E'): return False
else: return False
return is_num
方法——状态机(大神代码)
这个题的官方解法用状态机,参考大神解析和代码
状态机解法
class Solution:
def isNumber(self, s: str) -> bool:
states = [
{ ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'
{ 'd': 2, '.': 4 } , # 1. 'sign' before 'e'
{ 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'
{ 'd': 3, 'e': 5, ' ': 8 }, # 3. 'digit' after 'dot'
{ 'd': 3 }, # 4. 'digit' after 'dot' (‘blank’ before 'dot')
{ 's': 6, 'd': 7 }, # 5. 'e'
{ 'd': 7 }, # 6. 'sign' after 'e'
{ 'd': 7, ' ': 8 }, # 7. 'digit' after 'e'
{ ' ': 8 } # 8. end with 'blank'
]
p = 0 # start with state 0
for c in s:
if '0' <= c <= '9': t = 'd' # digit
elif c in "+-": t = 's' # sign
elif c in "eE": t = 'e' # e or E
elif c in ". ": t = c # dot, blank
else: t = '?' # unknown
if t not in states[p]: return False
p = states[p][t]
return p in (2, 3, 7, 8)
-----2021-01-03-----很多情况都在提交的时候才发现没考虑到,要注意!---------------