题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分: 若干空格 一个小数或者整数 (可选)一个 '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
示例 3:
输入:s = "."
输出:false
示例 4:
输入:s = " .1 "
输出:true
提示:
1 <= s.length <= 20
s 仅含英文字母(大写和小写),数字(0-9),加号 '+' ,减号 '-' ,空格 ' ' 或者点 '.' 。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解决方法
方法一:有限状态自动机
思路:通过对字符串的每一个元素从头开始遍历,若满足对应的转移条件,则跳转到对应的状态,否则提前返回False,若最终状态满足结束状态,则返回True,否则返回False。
状态有:
0:字符串开始的空格 1:幂符号前的’+’,’-‘ 2: 幂符号前的小数点前的数字 3:小数点以及幂符号前小数点后的数字 当小数点前为空格时,小数点以及幂符号前小数点后的数字
5:幂符号 6:幂符号后的‘+’,‘-’ 7:幂符号后的数字 8:字符串结束时的空格
根据题目可以写出状态转移规则,具体可见代码里states,其中states中第几个元素代表第一个状态,每个元素为一个字典,字典里key,value分别代表下一个状态的值以及下一个状态。
合法的结束状态:
2, 3, 7, 8
符号定义:
d: 数字 s: ‘+’ or ‘-’ e: ‘e’ or ‘E’ c: ‘.’ or ‘ ‘ ?: 未知符号
代码:
class Solution:
def isNumber(self, s: str) -> bool:
states = [
{' ': 0, 's': 1, 'd': 2, '.': 4}, # 0 字符串开始的空格
{'d': 2, '.': 4}, # 1 幂符号前的'+','-'
{'d': 2, '.': 3, 'e': 5, ' ': 8}, # 2 幂符号前的小数点前的数字
{'d': 3, 'e': 5, ' ': 8}, # 3 小数点以及幂符号前小数点后的数字
{'d': 3}, # 4 当小数点前为空格时,小数点以及幂符号前小数点后的数字
{'s': 6, 'd': 7}, # 5 幂符号
{'d': 7}, # 6 幂符号后的‘+’,‘-’
{'d': 7, ' ': 8}, # 7 幂符号后的数字
{' ': 8}, # 8 字符串结束时的空格
]
p = 0 # 从状态0开始
for char in s:
if '0' <= char <= '9': t = 'd'
elif char in 'eE': t = 'e'
elif char in '. ': t = char
elif char in '+-': t = 's'
else: t = '?'
if t not in states[p]: return False
p = states[p][t]
return p in (2, 3, 7, 8)
复杂度分析:
时间复杂度:O(n), n为字符串长度 空间复杂度:O(1)