LeetCode Python 065 Valid Number

Validate if a given string is numeric.

Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.

Example:

"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
  • 猜猜看我输入的是不是一个数呢?
class Solution:
# @param s, a string
# @return a boolean
    def isNumber(self, s):
        num_s=s.strip().lower()
        (_start, _num1, _e, _signed_e, _null_point, _num_point, _num2, _num3)=range(8)
        state=_start
        for c in num_s:
            if state==_start:
                if c=='.':
                    state=_null_point
                elif c=='-' or c=='+':
                    state=_start
                elif ord(c)>=48 and ord(c)<=57:
                    state=_num1
                else:
                    return False
            elif state==_num1:
                if c=='.':
                    state=_num_point
                elif c=='e':
                    state=_e
                elif ord(c)>=48 and ord(c)<=57:
                    state=_num1
                else:
                    return False
            elif state==_null_point:
                if ord(c)>=48 and ord(c)<=57:
                    state=_num2
                else:
                    return False
            elif state==_num_point:
                if ord(c)>=48 and ord(c)<=57:
                    state=_num2
                elif c=='e':
                    state=_e
                else:
                    return False
            elif state==_num2:
                if ord(c)>=48 and ord(c)<=57:
                    state=_num2
                elif c=='e':
                    state=_e
                else:
                    return False
            elif state==_e:
                if ord(c)>=48 and ord(c)<=57:
                    state=_num3
                elif c=='-' or c=='+':
                    state=_signed_e
                else:
                    return False
            elif state==_signed_e:
                if ord(c)>=48 and ord(c)<=57:
                    state=_num3
                else:
                    return False
            elif state==_num3:
                if ord(c)>=48 and ord(c)<=57:
                    state=_num3
                else:
                    return False
        if state==_num_point or state==_num1 or state==_num2 or state==_num3:
            return True
        else:
            return False

  • 在常规的解法下,完成这个问题是个折磨:
    • 扒光洗净之后从头开始判断。
    • 把整数、浮点数、科学计数法、正负号的逻辑全走一遍.
    • 然后就是如此,这段代码(我拷的)依然存在漏洞,比如“++1”会被识别成正确的。
  • 与之相似但是更聪明的方法是进一步将逻辑抽象,构造出完全的逻辑映射:
class Solution(object):
  def isNumber(self, s):
      """
      :type s: str
      :rtype: bool
      """
      #define a DFA
      state = [{}, 
              {'blank': 1, 'sign': 2, 'digit':3, '.':4}, 
              {'digit':3, '.':4},
              {'digit':3, '.':5, 'e':6, 'blank':9},
              {'digit':5},
              {'digit':5, 'e':6, 'blank':9},
              {'sign':7, 'digit':8},
              {'digit':8},
              {'digit':8, 'blank':9},
              {'blank':9}]
      currentState = 1
      for c in s:
          if c >= '0' and c <= '9':
              c = 'digit'
          if c == ' ':
              c = 'blank'
          if c in ['+', '-']:
              c = 'sign'
          if c not in state[currentState].keys():
              return False
          currentState = state[currentState][c]
      if currentState not in [3,5,8,9]:
          return False
      return True
  • 这可以想象成前一种思路的精华形式。
  • 把字符串依次输入,整个判断的逻辑存在于字典列表里。每一个字符后更新一次状态。

  • 如果想不清什么是对的,不妨想想什么是错的,不知道什么是错的,不妨问问编译器:

  • 每次程序报错,大多数人都会急匆匆地去看行数,这里给你看个大宝贝:
AttributeError 试图访问一个对象没有的属性

IOError 输入/输出异常

ImportError 无法引入模块或包

IndentationError 代码没有正确对齐

IndexError 索引越界

KeyError 试图访问字典里不存在的键

KeyboardInterrupt Ctrl+C被按下

NameError 尝试访问一个没有申明的变量

SyntaxError 代码不能编译

TypeError 传入对象类型与要求的不符合

UnboundLocalError 试图访问一个还未被设置的局部变量

ValueError 传入一个调用者不期望的值!!
  • 尝试一下
>>> float('0')
0.0
>>> float('++1')
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    float('++1')
ValueError: could not convert string to float: '++1'
>>> float('-1e-2')
-0.01
>>> float('-1e -2')
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    float('-1e -2')
ValueError: could not convert string to float: '-1e -2'
>>> float('shuang')
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    float('shuang')
ValueError: could not convert string to float: 'shuang'
  • 所以说,python还有另外一种可以优雅解决这个问题的方法:
class Solution:
    def isNumber(self, s):
        """
        :type s: str
        :rtype: bool
        """
        try: 
            float(s)
        except ValueError: 
            return False
        else: 
            return True
  • 大概意思就是:
    • “float,给你看个宝贝”
    • “这是什么啊?”
    • “别管是什么,我放进去试试”
    • “疼疼疼!快拿出去!”
    • “看来她不喜欢这个……”

猜你喜欢

转载自blog.csdn.net/weixin_41084236/article/details/81328185