有效数字

有效数字

CategoryDifficultyLikesDislikes
algorithmsHard (27.34%)310-

Tags

math | string

Companies

linkedin

有效数字(按顺序)可以分成以下几个部分:

  1. 一个 小数 或者 整数
  2. (可选)一个 'e' 或 'E' ,后面跟着一个 整数

小数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符('+' 或 '-'
  2. 下述格式之一:
    1. 至少一位数字,后面跟着一个点 '.'
    2. 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
    3. 一个点 '.' ,后面跟着至少一位数字

整数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符('+' 或 '-'
  2. 至少一位数字

部分有效数字列举如下:["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]

部分无效数字列举如下:["abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"]

给你一个字符串 s ,如果 s 是一个 有效数字 ,请返回 true 。

示例 1:

1
2
输入:s = "0"
输出:true

示例 2:

1
2
输入:s = "e"
输出:false

示例 3:

1
2
输入:s = "."
输出:false

提示:

  • 1 <= s.length <= 20
  • s 仅含英文字母(大写和小写),数字(0-9),加号 '+' ,减号 '-' ,或者点 '.' 。

Discussion | Solution

解法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
struct Solution;

// @lc code=start
impl Solution {
    /// ## 解题思路
    pub fn is_number(s: String) -> bool {
        fn is_decimal(s: &str) -> bool {
            let (mut num, mut dot) = (false, false);
            for (i, c) in s.chars().enumerate() {
                match c {
                    '+' | '-' if i == 0 => {}
                    '0'..='9' => num = true,
                    '.' if !dot => dot = true,
                    _ => return false,
                }
            }
            num
        }

        fn is_int(s: &str) -> bool {
            let mut num = false;
            for (i, c) in s.chars().enumerate() {
                match c {
                    '+' | '-' if i == 0 => {}
                    '0'..='9' => num = true,
                    _ => return false,
                }
            }
            num
        }

        if let Some(e) = s.chars().position(|c| c == 'e' || c == 'E') {
            is_decimal(&s[0..e]) && is_int(&s[e + 1..])
        } else {
            is_decimal(&s)
        }
    }
}
// @lc code=end
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class Solution {
private:
    bool isSpace(char c) { return c==' '; }
    bool isSgn(char c) { return (c=='+' || c=='-'); }
    bool isDot(char c) { return c=='.'; }
    bool isNum(char c) { return (c<='9' && c>='0'); }
    bool isE(char c) { return (c=='e'||c=='E'); }
public:
    /**
     ## 解题思路
       1. 使用i表示当前char的index,
       2. 按柜子依次check char,并++i;
       3. 用变量haveNum记录遍历当前时刻所得字符串是否得到合法数字;
       4. 遍历结束,判断haveNum;
     **/
    bool isNumber(string s) {
        int i = 0;
        bool haveNum = false;

        // skip space
        while(i<s.size() && isSpace(s[i])) ++i;

        // 判断符号位
        if (i<s.size() && isSgn(s[i])) ++i;

        // 检查.前是否有数字
        while(i<s.size() && isNum(s[i])) {
            haveNum=true;
            ++i;
        }

        // 检查.     
        if (i<s.size() && isDot(s[i])) ++i;

        // 检查.后面是否有num
        while(i<s.size() && isNum(s[i])) {
            haveNum=true;
            ++i;
        } 

        // 检查数字后面是否有e/E
        if (i<s.size()-1 && haveNum && isE(s[i])) {
            haveNum = false;      //e后面必须要有数字,先设为false
            ++i;
            if (i<s.size() && isSgn(s[i])) {  //e后面的符号
                ++i;
            }
        };

        // 检查e/E 后面的数字
        while(i<s.size() && isNum(s[i])) {
            haveNum=true;       //e后面有数字,则
            ++i;
        }

        //末尾空字符
        while(i<s.size() && isSpace(s[i])) ++i;

        //
        return (i==s.size() && haveNum);
    }

};
updatedupdated2024-08-252024-08-25