• 【LeetCode】面试题20. 表示数值的字符串


    题目:

    思路:

    1、分析规律,逻辑判断,需要特别注意特殊情况。
    2、确定有限自动机(DFA)。构造DFA可以先写正则表达式再转换成DFA,也可以直接写。如下图所示DFA中红色为终止状态,蓝色为中间状态。DFA从状态0开始接收字符,当输入字符结束时当前状态处于中间状态,则拒绝;如果到达终止状态,则接受。状态0和8用于处理开始和结束时的空格。

    红色的3个终止状态分别表示小数点前的数字、小数点后的数字、e后的数字。同样都是数字但是位置不同,不是一个状态。比如小数点前的数字可以转移到小数点,但是小数点后的数字无法转移到小数点。

    ' ' '+/-' '0-9' '.' 'e/E' other
    0 0 1 6 2 -1 -1
    1 -1 -1 6 2 -1 -1
    2 -1 -1 3 -1 -1 -1
    3 8 -1 3 -1 4 -1
    4 -1 7 5 -1 -1 -1
    5 8 -1 5 -1 -1 -1
    6 8 -1 6 3 4 -1
    7 -1 -1 5 -1 -1 -1
    8 8 -1 -1 -1 -1 -1

    代码:

    Python

    class Solution(object):
        def isNumber(self, s):
            """
            :type s: str
            :rtype: bool
            """
            point = -1
            e = -1
            s = s.strip(' ')
            if len(s) == 0:
                return False
            firstNum = -1
            for i in range(len(s)):
                # +/-只能出现在第一个字符或e之后, 但不能是最后一个字符
                if s[i] in ['+', '-']:
                    if (i != 0 and s[i-1] not in ['e', 'E']) or i == len(s) - 1:
                        return False
                elif s[i] == '.':
                    # .前面出现过.||.前没有数字且是最后一个字符, False
                    if point != -1 or (firstNum == -1 and i == len(s) - 1):
                        return False
                    else:
                        point = i
                elif s[i] in ['e', 'E']:
                    # e是第一个或最后一个字符||e前面出现过e||e前面没有数字, False
                    if i == 0 or i == len(s) - 1 or e != -1 or firstNum == -1:
                        return False
                    # 出现过e, 且e之后不能出现.
                    else:
                        e = i
                        point = i
                elif '0' <= s[i] <= '9':
                    if firstNum == -1:
                        firstNum = i
                    continue
                else:
                    return False
            return True
    
    class Solution(object):
        def isNumber(self, s):
            """
            :type s: str
            :rtype: bool
            """
            numSeen = False
            dotSeen = False
            eSeen = False
            # 去掉前后的空格
            s = s.strip(' ')
            if len(s) == 0:
                return False
            for i in range(len(s)):
                if '0' <= s[i] <= '9':
                    numSeen = True
                # .之前不能出现.和e
                elif s[i] == '.':
                    if dotSeen or eSeen:
                        return False
                    else:
                        dotSeen = True
                # e之前不能出现e, 且必须出现数字
                elif s[i] in ['e', 'E']:
                    if eSeen or not numSeen:
                        return False
                    else:
                        eSeen = True
                        numSeen = False  # e之后也要出现数字
                elif s[i] in ['-', '+']:
                    if i != 0 and s[i-1] not in ['e', 'E']:
                        return False
                else:
                    return False
            return numSeen
    
    class Solution(object):
        def getIndex(self, c):
            myIndex = {
                ' ': 0, 
                '+': 1, 
                '-': 1, 
                'num': 2, 
                '.': 3, 
                'e': 4, 
                'E': 4}
            if '0' <= c <= '9':
                return myIndex.get('num')
            else:
                return myIndex.get(c, -1)
        def isNumber(self, s):
            """
            :type s: str
            :rtype: bool
            """
            state = 0
            finals = 0b101101000 # 终止状态3/5/6/8
            transfer = [
                [0, 1, 6, 2, -1], 
                [-1, -1, 6, 2, -1],
                [-1, -1, 3, -1, -1],
                [8, -1, 3, -1, 4],
                [-1, 7, 5, -1, -1],
                [8, -1, 5, -1, -1],
                [8, -1, 6, 3, 4],
                [-1, -1, 5, -1, -1],
                [8, -1, -1, -1, -1]]
            for c in s:
                id = self.getIndex(c)
                if id < 0:
                    return False
                state = transfer[state][id]
                if state < 0:
                    return False
            # 1 << state表示1向左移动state位
            return (finals & (1 << state)) > 0
    

    相关问题

  • 相关阅读:
    pyenv
    [20200724NOIP提高组模拟T3]终章-剑之魂
    [20200724NOIP提高组模拟T2]圣章-精灵使的魔法语
    [20200724NOIP提高组模拟T1]序章-弗兰德的秘密
    [20200723NOIP提高组模拟T1]同余
    [SDOI2008]仪仗队
    P3195 [HNOI2008]玩具装箱
    [20200722NOIP提高组模拟T4]词韵
    [20200721NOIP提高组模拟T3]最小代价
    [20200721NOIP提高组模拟T1]矩阵
  • 原文地址:https://www.cnblogs.com/cling-cling/p/13024010.html
Copyright © 2020-2023  润新知