1. 正向思路

此题要判断字符串是否表示数值?通过对示例的观察可以发现能判断为数值的字符串大致可分为以下四种:

- 是否有前/后 空格或符号位(即 + 、- 两种符号)?
- 是否有整数?
- 是否有小数点?
- 是否有指数e/E?

由于每种还包含多个小方向,于是掌柜第一想法是用 正则表达式来解此题。

2.正向解法 --> 正则表达式图解

  • 首先我们来解决是否有前/后 空格或符号位? 的正则表达式
    (这里我们采用re.match()函数: 表示必须从字符串开头匹配,图解省略这里):

    • 2.1 正则匹配字符串首尾的写法(看标红框住的部分):
      图片说明
    • 2.2 接着匹配0个或多个任意空白字符的写法:
    • 2.3 然后匹配 0到 1个前面有正负号的字符写法:
  • 其次解决是否有整数,小数点?的正则表达式:

    • 2.4 匹配0到1个前面包含1个数字(比如 100)或 数字+小数点+数字的字符(比如3.1416)的写法:
      图片说明
    • 2.5 匹配1个或多个 小数点 + 数字的字符(比如 .15)的写法:
      图片说明
    • 2.6 匹配1个或多个 数字 + 小数点的字符(比如 3.)的写法:
      图片说明
  • 最后解决是否有指数e/E ?的正则表达式:

    • 2.7 匹配0到1个前面有e/E指数 + 0到1个正负号 + 1个或多个数字的字符写法:
      图片说明

3.核心代码

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param str string字符串 
# @return bool布尔型
import re

class Solution:
    def isNumeric(self, str):
        match_Obj = re.match('^\s*[+-]{0,1}((\d)+((\.)(\d)+){0,1}|((\.)(\d)+)|((\d)+(\.)))([eE][+-]{0,1}[\d]+){0,1}\s*$',str)
        if match_Obj:
            return True
        else:
            return False

4.复杂度分析

  • 时间复杂度:O(n) (与该字符串的长度有关,每个字符最多被匹配一次)
  • 空间复杂度:O(n)

-------------------------------------------------我是不鼓励但可尝试的投机取巧分割线-----------------------------------------------

5. Python 异常捕获法

  • 5.1 思路
    由于我们观察所有表示数值的字符串可以发现,他们都可以转换为浮点数!!!
    所以可以采用浮点数float() + try ...except 异常捕获的方法来判断字符串。

  • 5.2 核心代码

    class Solution:
      def isNumeric(self , str ):
          # write code here
          try:
              float(str)
          except:
              return False
          return True

    代码很简单,不过如果此题面试遇到,估计面试官也不会认可这个解法🤣,大家就当拓展思路了解一下,面试还是不要采用!!!

此题应该真正想考的是 确定有限状态自动机 这个思路。

不过有点复杂,所以先了解简单的解法,后面再补上该解法🤝。