leetcode 每日一题 65. 有效数字

DFA法

思路:

确定的有穷自动机,相关参考8. 字符串转换整数 (atoi)

 

遍历字符串,遇到的字符总共有6种。(空格,正负号,数字,小数点,字符e,无效字符)

可能出现的状态有11种:

start:初始状态

signed:符号态

integer:整数态

sDot:特殊的初始小数点态(小数点之前为符号或空格)

dot:小数点态(小数之前为整数)

decimals:小数态

e:指数符号态

eSigned:指数正负号态

index:指数态

eSpace:尾部空格态

end:无效截止态

各种状态在自己状态下遇到6种字符要更新的状态如下图所示:

每种状态下代表之前遍历过的字符是否能转为数字:

start:False

signed:False

integer:True

sDot:False

dot:True

decimals:True

e:False

eSigned:False

index:True

eSpace:True

end:False

代码:

class Automaton:
    def __init__(self):
        self.state = 'start'
        self.isNum = False
        self.table = {
            'start': ['start','signed','integer','sDot', 'end','end'],
            'signed': ['end','end','integer','sDot','end', 'end'],
            'integer': ['eSpace','end','integer','dot','e','end'],
            'sDot':['end','end','decimals','end','end','end'],
            'dot': ['eSpace','end','decimals','end','e','end'],
            'decimals': ['eSpace','end','decimals','end','e','end'],
            'e': ['end','eSigned','index','end','end','end'],
            'eSigned': ['end','end','index','end','end','end'],
            'index': ['eSpace','end','index','end','end','end'],
            'eSpace': ['eSpace','end','end','end','end','end']
        }
    def get_col(self, c):
        if c.isspace():
            return 0
        if c == '+' or c == '-':
            return 1
        if c.isdigit():
            return 2
        if c == '.':
            return 3
        if c == 'e':
            return 4
        return 5

    def get(self, c):
        self.state = self.table[self.state][self.get_col(c)]
        if self.state == 'start':
            self.isNum = False
        elif self.state == 'signed':
            self.isNum = False
        elif self.state == 'integer':
            self.isNum = True
        elif self.state == 'sDot':
            self.isNum = False
        elif self.state == 'dot':
            self.isNum = True
        elif self.state == 'decimals':
            self.isNum = True
        elif self.state == 'e':
            self.isNum = False
        elif self.state == 'eSigned':
            self.isNum = False
        elif self.state == 'index':
            self.isNum = True
        elif self.state == 'end':
            self.isNum = False
        elif self.state == 'eSpace':
            self.isNum = True
class Solution:
    def isNumber(self, s: str) -> bool:
        automaton = Automaton()
        for c in s:
            automaton.get(c)
            if automaton.state == "end":
                break
        return automaton.isNum

 

posted @ 2020-06-07 16:20  nil_f  阅读(176)  评论(0)    收藏  举报