玩命加载中 . . .

20-表示数值的字符串


剑指 Offer 20. 表示数值的字符串

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。

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

  1. 若干空格
  2. 一个 小数 或者 整数
  3. (可选)一个 ‘e’ 或 ‘E’ ,后面跟着一个 整数
  4. 若干空格

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

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

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

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

部分数值列举如下:

["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]

部分非数值列举如下:

["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]

示例 1:

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

method

enum State {
    STATE_INITIAL,  // 起始的空格
    STATE_INT_SIGN, // 符号位
    STATE_INTEGER,  // 整数部分
    STATE_POINT,    // 左侧有整数的小数点
    STATE_POINT_WITHOUT_INT,    // 左侧无整数的小数点
    STATE_FRACTION, // 小数部分
    STATE_EXP,      // 字符e/E
    STATE_EXP_SIGN, // 指数部分的符号位
    STATE_EXP_NUMBER,   // 指数部分的整数部分
    STATE_END   // 末尾的空格
};

enum CharType {
    CHAR_NUMBER,    // 数字
    CHAR_EXP,       // 指数e/E
    CHAR_POINT,     // 点
    CHAR_SIGN,      // 符号
    CHAR_SPACE,     // 空格
    CHAR_ILLEGAL    // 非法输入
};

CharType toCharType(char ch) {
    if (ch >= '0' && ch <= '9') return CHAR_NUMBER;
    else if (ch == 'e' || ch == 'E') return CHAR_EXP;
    else if (ch == '.') return CHAR_POINT;
    else if (ch == '+' || ch == '-') return CHAR_SIGN;
    else if (ch == ' ') return CHAR_SPACE;
    else return CHAR_ILLEGAL;
}

bool isNumber(string s) {
    unordered_map<State, unordered_map<CharType, State>> transfer {
        {
            STATE_INITIAL, {
                {CHAR_SPACE, STATE_INITIAL},
                {CHAR_NUMBER, STATE_INTEGER},
                {CHAR_POINT, STATE_POINT_WITHOUT_INT},
                {CHAR_SIGN, STATE_INT_SIGN}
            }
        }, {
            STATE_INT_SIGN, {
                {CHAR_NUMBER, STATE_INTEGER},
                {CHAR_POINT, STATE_POINT_WITHOUT_INT}
            }
        }, {
            STATE_INTEGER, {
                {CHAR_NUMBER, STATE_INTEGER},
                {CHAR_EXP, STATE_EXP},
                {CHAR_POINT, STATE_POINT},
                {CHAR_SPACE, STATE_END}
            }
        }, {
            STATE_POINT, {
                {CHAR_NUMBER, STATE_FRACTION},
                {CHAR_EXP, STATE_EXP},
                {CHAR_SPACE, STATE_END}
            }
        }, {
            STATE_POINT_WITHOUT_INT, {
                {CHAR_NUMBER, STATE_FRACTION}
            }
        }, {
            STATE_FRACTION, {
                {CHAR_NUMBER, STATE_FRACTION},
                {CHAR_EXP, STATE_EXP},
                {CHAR_SPACE, STATE_END}
            }
        }, {
            STATE_EXP, {
                {CHAR_NUMBER, STATE_EXP_NUMBER},
                {CHAR_SIGN, STATE_EXP_SIGN}
            }
        }, {
            STATE_EXP_SIGN, {
                {CHAR_NUMBER, STATE_EXP_NUMBER}
            }
        }, {
            STATE_EXP_NUMBER, {
                {CHAR_NUMBER, STATE_EXP_NUMBER},
                {CHAR_SPACE, STATE_END}
            }
        }, {
            STATE_END, {
                {CHAR_SPACE, STATE_END}
            }
        }
    };
    
    State st = STATE_INITIAL;
    for (int i= 0; i < s.size(); i++) {
        CharType type = toCharType(s[i]);
        if (transfer[st].find(type) == transfer[st].end()) {
            return false;
        }
        else {
            st = transfer[st][type];
        }
    }
    return st == STATE_INTEGER || st == STATE_POINT || st == STATE_FRACTION || st == STATE_EXP_NUMBER || st == STATE_END;
}

文章作者: kunpeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kunpeng !
  目录