TOC
题目
验证给定的字符串是否可以解释为十进制数字。
例如:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
" -90e3 " => true
" 1e" => false
"e3" => false
" 6e-1" => true
" 99e2.5 " => false
"53.5e93" => true
" --6 " => false
"-+3" => false
"95a54e53" => false
说明: 我们有意将问题陈述地比较模糊。在实现代码之前,你应当事先思考所有可能的情况。这里给出一份可能存在于有效十进制数字中的字符列表:
数字 0-9
指数 - "e"
正/负号 - "+"/"-"
小数点 - "."
当然,在输入中,这些字符的上下文也很重要。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
首先,将问题分解一下。判断是否是有效十进制数条件:
- 不能包含字符串;
- 存在正/负号,除非中间有指数 e,否则不能再出现正/负号;并且正负号只能出现在数字开始,或者紧跟 e;
- e 不能出现在开始位置,并且紧跟数字9;
- 正确的数字都是数字结尾,或者数字加上’.‘结尾;
接下来,我们只需要根据上面条件构建状态表,每个状态只需关注转换后的状态即可:
数字0-9 | 指数e | 小数点. | 正/负号 | 其他 | |
---|---|---|---|---|---|
0 其实状态 | 1 | -1 | 8 | 6 | -1 |
1 纯数字 | 1 | 5 | 4 | -1 | -1 |
2 存在小数 | 2 | 5 | -1 | -1 | -1 |
3 存在指数 | 3 | -1 | -1 | -1 | -1 |
4 小数结尾 | 2 | 5 | -1 | -1 | -1 |
5 指数 | 3 | -1 | -1 | 7 | -1 |
6 正/负号 | 1 | -1 | 8 | -1 | -1 |
7 指数存在正负号 | 3 | -1 | -1 | -1 | -1 |
8 小数 | 2 | -1 | -1 | -1 | -1 |
代码
//状态机
func isNumber(s string) bool {
stateTable := [9][5]int{
// 0-9 e . -/+ other
{1, -1, 8, 6, -1}, // start -- 0
{1, 5, 4, -1, -1}, // 0-9 -- 1
{2, 5, -1, -1, -1}, // .0-9 -- 2
{3, -1, -1, -1, -1}, // e0-9 -- 3
{2, 5, -1, -1, -1}, // 0-9. -- 4
{3, -1, -1, 7, -1}, // e -- 5
{1, -1, 8, -1, -1}, // -/+ -- 6
{3, -1, -1, -1, -1}, // e-/+ -- 7
{2, -1, -1, -1, -1}, // . -- 8
}
s = strings.Trim(s, " ")
if s == "." {
return false
}
state := 0
for _, v := range s {
n := getN(v)
state = stateTable[state][n]
if state < 0 {
return false
}
}
if state > 0 && state <= 4 {
return true
}
return false
}
func getN(n rune) int {
s := string(n)
switch s {
case "-", "+":
return 3
case "e":
return 1
case ".":
return 2
}
if s >= "0" && s <= "9" {
return 0
}
return 4
}
「真诚赞赏,手留余香」
真诚赞赏,手留余香
使用微信扫描二维码完成支付

comments powered by Disqus