有效数字

Posted by Jason on Tuesday, January 28, 2020

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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

首先,将问题分解一下。判断是否是有效十进制数条件:

  1. 不能包含字符串;
  2. 存在正/负号,除非中间有指数 e,否则不能再出现正/负号;并且正负号只能出现在数字开始,或者紧跟 e;
  3. e 不能出现在开始位置,并且紧跟数字9;
  4. 正确的数字都是数字结尾,或者数字加上’.‘结尾;

接下来,我们只需要根据上面条件构建状态表,每个状态只需关注转换后的状态即可:

数字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
}

「真诚赞赏,手留余香」

Jason Blog

真诚赞赏,手留余香

使用微信扫描二维码完成支付


comments powered by Disqus