[M]O-20 表示数值的字符串

[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)如果遇到小数点

  1. 不可能连续出现两个小数点
  2. 小数点之前不可能已经出现E/e

所以,上述两个条件满足一个即return False
否则,置is_dot=True
(6)如果遇到e/E

  1. 前面必须有数字 not is_num
  2. 不可能已经出现E/e is_eorE

所以,上述两个条件满足一个即return False
否则,置is_eorE=True,且重置数字为False,因为e/E后面还必须有数字。
(例如1e(应该是False),最后应该到return isnum这一步,由于在判断e时候已经把isnum变为False,所以此时最后结果为False对的,如果不加这一条件,可能会因为前面第一个数字已经把isnum变成True而让最终结果错误)
(7)如果遇到**±**,正负号之可能出现在两种情况下:

  1. 在首位
  2. 在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-----很多情况都在提交的时候才发现没考虑到,要注意!---------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值