文章目录
- 题目描述
- 题目分析
- 法一:
- 完整代码:
- 法二:
- 完整代码:
题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
若干空格
一个 小数 或者 整数
(可选)一个 ‘e’ 或 ‘E’ ,后面跟着一个 整数
若干空格
小数(按顺序)可以分成以下几个部分:
(可选)一个符号字符(‘+’ 或 ‘-’)
下述格式之一:
至少一位数字,后面跟着一个点 ‘.’
至少一位数字,后面跟着一个点 ‘.’ ,后面再跟着至少一位数字
一个点 ‘.’ ,后面跟着至少一位数字
整数(按顺序)可以分成以下几个部分:
(可选)一个符号字符(‘+’ 或 ‘-’)
至少一位数字
部分数值列举如下:
[“+100”, “5e2”, “-123”, “3.1416”, “-1E-16”, “0123”]
部分非数值列举如下:
[“12e”, “1a3.14”, “1.2.3”, “±5”, “12e+5.4”]
示例 1:
输入:s = “0”
输出:true
示例 2:
输入:s = “e”
输出:false
题目分析
这道题其实刚上来的第一思路就是把所有的情况全部分析出来,然后分别处理。
不过这样做并不是很好,除非你能N刷这道题,不然考试或者面试的时候很容易漏情况导致调试半天心态崩掉。
包括用状态机做这个题,状态机做这个题要分出来八九种情况,还要找状态转移关系,也是很多很杂。
所以这道题最好用的方法就是异常判断,面试考试最好用的方法就是正则。
法一:
先来一个简单的方法, 其实题目要求就是判断科学计数法是否符合规范,使用python的float转换,如果能转换成功则是合规的。
所以直接用tyr异常判断就行了。
完整代码:
class Solution:def isNumber(self, s: str) -> bool:try:float(s)except:return Falsereturn True
法二:
面试考试遇到这道题,就直接正则吧。
先分析一下整体合规的式子:可有可无的正负号 + 小数或整数 + 可有可无的e + 可有可无的正负号 + 整数
先放代码 然后分析。
re.match(r'^[+-]?(\d+\.?\d*|\.\d+)([Ee][+-]?\d+)?$'
- 开头的^和结尾的$ 表示从开头匹配到结尾,要完整匹配整个输入字符串。
[+-]?
:表示匹配+
或者-
符号 ,0次或者1次。?
表示匹配前面的字符0次或1次。(\d+\.?\d*|\.\d+)
: 这一串表示匹配小数或者整数,|
字符表示或,将这一串分割成了两个部分.- 第一部分
\d+\.?\d*
,\d+
匹配1个或者多个数字,+
表示匹配前方字符一次或多次。\.?
表示匹配.
0次或1次,\d*
表示匹配数字0次或多次。 整个第一部分中有一个\.?
,表示小数点可有可无,也就是这一部分可以为小数,可以为整数。若为小数,则其前必有数字,后可有可无。 - 第二部分
\.\d+
,就是匹配了 小数点前无数,后面有数的情况。
- 第一部分
- ([Ee][+-]?\d+)?
:这一串主要是控制e以及后面的字符, 首先这一段是可有可无的,因为e本身就可有可无嘛,所以最后有一个?
表示前一段出现0次或1次。[Ee]
表示选择大写E或者小写e。e后面必有数字嘛,要么是正负号,要么就是数字。所以再加上,[+-]?
表示匹配+
或者-
符号 ,0次或者1次。\d+
匹配数字一次或多次。
完整代码:
class Solution:def isNumber(self, s: str) -> bool:import rereturn bool(re.match(r'^[+-]?(\d+\.?\d*|\.\d+)([Ee][+-]?\d+)?$',s.strip()))