题⽬描述
请实现⼀个函数⽤来判断字符串str是否表示数值(包括科学计数法的数字,⼩数和整数)。科学计数法的数字(按顺序)可以分成以下⼏个部分:
若⼲空格
⼀个整数或者⼩数
(可选)⼀个 ’ e ’ 或 ’ E ‘,后⾯跟着⼀个整数(可正可负)
若⼲空格
⼩数(按顺序)可以分成以下⼏个部分:
若⼲空格
(可选)⼀个符号字符(’+’ 或 ‘-’)
可能是以下描述格式之⼀:
⾄少⼀位数字,后⾯跟着⼀个点 ‘.’
⾄少⼀位数字,后⾯跟着⼀个点 ‘.’,后⾯再跟着⾄少⼀位数字
⼀个点 ‘.’,后⾯跟着⾄少⼀位数字
若⼲空格
整数(按顺序)可以分成以下⼏个部分:
若⼲空格
(可选)⼀个符号字符(’ + ’ 或 ’ - ‘)
⾄少⼀位数字
若⼲空格
例如,字符串["+100",“5e2”,"-123",“3.1416”,"-1E-16"] 都表示数值。
但是[“12e”,“1a3.14”,“1.2.3”,"+-5",“12e+4.3”] 都不是数值。
提示:
1 <= str.length <= 25
str 仅含英⽂字⺟(⼤写和⼩写),数字(0-9),加号 ‘+’,减号 ‘-’,空格 ’ ’ 或者点 ‘.’ 。
如果怀疑⽤例是不是能表示为数值的,可以使⽤python 的print(float(str)) 去查看
示例1 输⼊:“123.45e+6” 返回值:true
示例2 输⼊:“1.2.3” 返回值:false
思路及解答
暴力分析拆解
主要是分析好判断分⽀,可以定义⼏个变量:
hashNum : 是否已经有数字
hashE :是否已经有E
hasSign :是否已经有符号
hasDot :是否已经有⼩数点
⾸先,初始化当前的索引index =0,字符串头部的空格需要跳过。
循环判断索引是否在有效的范围内:
- 循环判断是否是数字,是数字则更新hasNum = true ,并且索引后移,直到不是数字的时候,跳出循环。
跳出循环后,需要判断当前的index 是否合法,不合法直接break
取出当前索引的字符c :
如果c 是e 或者E :
如果前⾯已经出现过E,或者前⾯没有数字,直接返回false
否则, hasE 置为true,其他的置为false,也就是E后⾯可以继续出现符号数字和⼩数点了
如果c 是“ + ”或者“ - ”:
前⾯如果已经出现过数字或者符号或者⼩数点,都不是合法的
否则hasSign 置为true,表示符号出现过
如果c 是⼩数点“ . ”
如果前⾯已经有⼩数点或者有E出现了,那么就是⾮法的,返回false
否则hasDot 置为true
如果c 为空格,直接跳出循环
否则,直接返回false
最后也需要跳过空格
最后判断是否合法的条件是:是否到达最后⼀个字符,并且出现过数字
这道题,其实本质是状态的切换,最最重要的⼀点,是 E 出现之后,其实⼩数点和符号,和数字,都是可以再出现的,可以理解为 E 就是⼀个分割线。
正则表达式
直接借助正则表达式进⾏匹配,但是并不太推荐这种解法:
O(n)时间复杂度
O(1)空间复杂度
有限状态机
使用确定有限状态机(DFA)来精确建模数值的判断过程。
有限状态机法:通过状态转移精确控制数值格式。定义9种状态,根据输入字符进行状态转移
时间复杂度:O(n)
空间复杂度:O(1)