JZ53 表示数值的字符串

描述

请实现一个函数用来判断字符串str是否表示数值(包括科学计数法的数字,小数和整数)。

提示:

1.1 <= str.length <= 20

2.str 仅含英文字母(大写和小写),数字(0-9),加号 '+' ,减号 '-' ,空格 ' ' 或者点 '.' 

3.如果怀疑用例是不是能表示为数值的,可以使用python的print(float(str))去查看。

官方题解:(1)https://blog.nowcoder.net/n/c05af3f3955d4cf08eade7073438b8c2?f=comment

(2)https://blog.nowcoder.net/n/c7b3aa6f22ae431fa6792a81ed8ca1b9?f=comment

  • 正则表达式解法和异常捕获法,但可能不是面试官想要的答案。
  • 这道题真正想考的是:有限状态自动机

先来看(1)的题解:

正则表达式,通过JZ52学习到了一定的正则表达式匹配之后,先来判断一下这道题是要判断字符串是否表示数值?

通过一些示例来看,我们大体可以将需要判断的条件归纳整理:

①是否有前后空格或者符号位?

②是否有整数?

③是否有小数点

④是否有指数e/E?

根据每个要点来进行判断,代码为:

match_Obj = re.match('^\s*[+-]{0,1}((\d)+((\.)(\d)+){0,1}|((\.)(\d)+)|((\d)+(\.)))([eE][+-]{0,1}[\d]+){0,1}\s*$',str)

首先是①的正则表达式,这里采用的是re.match()函数:表示必须从字符串开头匹配,先写出正则匹配字符串首尾的写法: 

'

^

&

'

为了判断是否首尾有任意个空格字符的写法:

'

^

\s*

\s*

&

'

为了匹配前面是否有0到1个正负号的符号位写法:

'

^

\s*

[+-]{0,1}

\s*

&

'

然后是解决整数和小数点的正则表达式:

为了匹配0到1个前面包含1个数字(比如 100)【这句话不是很明白哎】或 数字+小数点+数字的字符(比如3.1416)的写法:

'

^

\s*

[+-]{0,1}

((\d)+((\.)(\d)+){0,1}

\s*

&

'

为了匹配1个或多个小数点 + 数字的字符(比如 .15)的写法:

'

^

\s*

[+-]{0,1}

((\d)+((\.)(\d)+){0,1}

|((\.)(\d)+)

\s*

&

'

为了匹配1个或多个数字+小数点的字符(比如 3.)的写法:

'

^

\s*

[+-]{0,1}

((\d)+((\.)(\d)+){0,1}

|((\.)(\d)+)

|((\d)+(\.)))

\s*

&

'

可以看出,匹配数字为(\d),小数点为(\.) 。蓝色括号为包含所有整数和小数点匹配情况。

最后解决是否有指数e/E的正则表达式?

'

^

\s*

[+-]{0,1}

((\d)+((\.)(\d)+){0,1}

|((\.)(\d)+)

|((\d)+(\.))

([eE][+-]{0,1}[\d]+){0,1}

\s*

&

'

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @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

异常捕获法:将字符串转换为浮点数,采用浮点数float() + try ...except 异常捕获的方法来判断字符串。

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

再来看(2)的题解:有限状态自动机

先来了解一下有限状态自动机,大家叫它字符串匹配算法。https://blog.csdn.net/tyler_download/article/details/52549315

图中的两个圆圈叫节点,用于表示状态,这个图可以看成有两个状态分别是0和1。每个节点都有若干条边相连,当处于某个状态时,如果输入的字符跟该节点出发的某条边的内容一样,就会引起状态的转变。

状态机会有一个初始节点,和一个接收节点,以上图为例,我们可以设置初始节点为0,接收节点为1,当进行一系列的输入,使得状态机的状态不断变化,只要最后一个输入使得状态机处于接收节点,那么就表明当前输入可以被状态机接收。

根据字符类型和合法数值的特点,先定义状态。

字符类型:
空格 「 」、数字「 0—9 」 、正负号 「 +- 」 、小数点 「 .」 、幂符号 「 eE 」 
状态定义:
按照字符串从左到右的顺序,定义以下 9 种状态。
1.开始的空格
2.幂符号前的正负号
3.小数点前的数字
4.小数点、小数点后的数字
5.当小数点前为空格时,小数点、小数点后的数字
6.幂符号
7.幂符号后的正负号
8.幂符号后的数字
9.结尾的空格

结束状态:合法的结束状态有 2, 3, 7, 8

class Solution:
    def isNumeric(self , str ):
        # write code here
        states = [
            { ' ': 0, 's': 1, 'd': 2, '.': 4 }, # 0. start with 'blank'
            { 'd': 2, '.': 4 } ,                # 1. 'sign' before 'e'
            { 'd': 2, '.': 3, 'e': 5, ' ': 8 }, # 2. 'digit' before 'dot'
            { 'd': 3, 'e': 5, ' ': 8 },         # 3. 'digit' after 'dot'
            { 'd': 3 },                         # 4. 'digit' after 'dot' (‘blank’ before 'dot')
            { 's': 6, 'd': 7 },                 # 5. 'e'
            { 'd': 7 },                         # 6. 'sign' after 'e'
            { 'd': 7, ' ': 8 },                 # 7. 'digit' after 'e'
            { ' ': 8 }                          # 8. end with 'blank'
        ]
        p = 0                           # start with state 0
        for c in str:
            if '0' <= c <= '9': t = 'd' # digit elif c in "+-": t = 's' # sign elif c in "eE": t = 'e' # e&nbs***bsp;E elif c in ". ": t = c # dot, blank else: t = '?' # unknown if t not in states[p]: return False p = states[p][t] return p in (2, 3, 7, 8)

可是!牛客网提交有用例错误哎,等我再熟悉点再来改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值