剑指offer

面试题20. 表示数值的字符串

2020-03-13  本文已影响0人  人一己千

题目

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"0123"及"-1E-16"都表示数值,但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法

正则表达式

这是最简单的方法,因为这就是一个正则题目。不过由于我的正则写的太少。
这是别人的代码:

作者:victoria-zhou
链接:https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/solution/onpythonjie-ti-wu-fa-luo-ji-pan-duan-regexdfadeng-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

import re
class Solution:
    p = re.compile(r'^[+-]?(\.\d+|\d+\.?\d*)([eE][+-]?\d+)?$')
    def isNumber(self, s: str) -> bool:
        return bool(self.p.match(s.strip()))

限定性有限自动机

总结出相应的状态和状态之间的转化函数。

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

讲道理

  1. 通过e分割为底数和指数部分;
  2. 底数只能包含数字正负号和小数点,指数只能包含正负号和数字;
  3. 正负号出现的话只能在数字的第一个位置;
  4. 小数点只能有一个;
    通过这几条规则的就是正确的答案。
class Solution(object):
    def isNumber(self, s):
        """
        :type s: str
        :rtype: bool
        """
        # 分开指数和底数进行判断
        s = s.lower().strip()
        e_pos = s.find('e')
        if e_pos == -1:
            print(-1)
            return self.judge_d(s)
        else:
            d_str = s[:e_pos]
            p_str = s[e_pos+1:]
            return self.judge_d(d_str) and self.judge_p(p_str)
        
    def judge_d(self,num):
        result = False
        point = False
        for i,c in enumerate(num):
            if c not in '0123456789+-.':
                return False
            elif c in '+-' :
                if i != 0 : return False
            elif c == '.' :
                if point: return False
                else: point = True
            else:
                result = True
        return result
    
    def judge_p(self,num):
        result = False
        if num == "":
            return False
        for i,c in enumerate(num):
            if c not in '0123456789+-':
                return False
            elif c in '+-' :
                if i != 0:
                    return False
            else:
                result = True
            
        return result
上一篇下一篇

猜你喜欢

热点阅读