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

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

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

若干空格
一个 小数 或者 整数
(可选)一个 'e' 或 'E' ,后面跟着一个 整数
若干空格
小数(按顺序)可以分成以下几个部分:

(可选)一个符号字符('+' 或 '-')
下述格式之一:
至少一位数字,后面跟着一个点 '.'
至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
一个点 '.' ,后面跟着至少一位数字
整数(按顺序)可以分成以下几个部分:

(可选)一个符号字符('+' 或 '-')
至少一位数字
部分数值列举如下:

["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]
部分非数值列举如下:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

import java.util.HashMap;
import java.util.Map;

class Solution {
    public boolean isNumber(String s) {
        /**
         * 一个State遇到CharType转移到另一个State
         */
        Map<State, Map<CharType, State>> transfer = new HashMap<State, Map<CharType, State>>();

        /**
         * 初始状态
         */
        Map<CharType, State> initialMap = new HashMap<CharType, State>() {{
            /**
             * 空格
             */
            put(CharType.CHAR_SPACE, State.STATE_INITIAL);
            /**
             * 数字
             */
            put(CharType.CHAR_NUMBER, State.STATE_INTEGER);
            /**
             * 小数点
             */
            put(CharType.CHAR_POINT, State.STATE_POINT_WITHOUT_INT);
            /**
             * 符号
             */
            put(CharType.CHAR_SIGN, State.STATE_INT_SIGN);
        }};
        transfer.put(State.STATE_INITIAL, initialMap);

        /**
         * 符号
         */
        Map<CharType, State> intSignMap = new HashMap<CharType, State>() {{
            put(CharType.CHAR_NUMBER, State.STATE_INTEGER);
            put(CharType.CHAR_POINT, State.STATE_POINT_WITHOUT_INT);
        }};
        transfer.put(State.STATE_INT_SIGN, intSignMap);

        /**
         * 整数部分
         */
        Map<CharType, State> integerMap = new HashMap<CharType, State>() {{
            put(CharType.CHAR_NUMBER, State.STATE_INTEGER);
            put(CharType.CHAR_EXP, State.STATE_EXP);
            put(CharType.CHAR_POINT, State.STATE_POINT);
            put(CharType.CHAR_SPACE, State.STATE_END);
        }};
        transfer.put(State.STATE_INTEGER, integerMap);

        /**
         * 小数点
         */
        Map<CharType, State> pointMap = new HashMap<CharType, State>() {{
            put(CharType.CHAR_NUMBER, State.STATE_FRACTION);
            put(CharType.CHAR_EXP, State.STATE_EXP);
            put(CharType.CHAR_SPACE, State.STATE_END);
        }};
        transfer.put(State.STATE_POINT, pointMap);

        Map<CharType, State> pointWithoutIntMap = new HashMap<CharType, State>() {{
            put(CharType.CHAR_NUMBER, State.STATE_FRACTION);
        }};
        transfer.put(State.STATE_POINT_WITHOUT_INT, pointWithoutIntMap);

        /**
         * 小数部分
         */
        Map<CharType, State> fractionMap = new HashMap<CharType, State>() {{
            put(CharType.CHAR_NUMBER, State.STATE_FRACTION);
            put(CharType.CHAR_EXP, State.STATE_EXP);
            put(CharType.CHAR_SPACE, State.STATE_END);
        }};
        transfer.put(State.STATE_FRACTION, fractionMap);

        /**
         * e
         */
        Map<CharType, State> expMap = new HashMap<CharType, State>() {{
            put(CharType.CHAR_NUMBER, State.STATE_EXP_NUMBER);
            put(CharType.CHAR_SIGN, State.STATE_EXP_SIGN);
        }};
        transfer.put(State.STATE_EXP, expMap);

        /**
         * 指数符号
         */
        Map<CharType, State> expSignMap = new HashMap<CharType, State>() {{
            put(CharType.CHAR_NUMBER, State.STATE_EXP_NUMBER);
        }};
        transfer.put(State.STATE_EXP_SIGN, expSignMap);

        /**
         * 指数
         */
        Map<CharType, State> expNumberMap = new HashMap<CharType, State>() {{
            put(CharType.CHAR_NUMBER, State.STATE_EXP_NUMBER);
            put(CharType.CHAR_SPACE, State.STATE_END);
        }};
        transfer.put(State.STATE_EXP_NUMBER, expNumberMap);

        /**
         * 终止
         */
        Map<CharType, State> endMap = new HashMap<CharType, State>() {{
            put(CharType.CHAR_SPACE, State.STATE_END);
        }};
        transfer.put(State.STATE_END, endMap);

        int length = s.length();
        State state = State.STATE_INITIAL;

        for (int i = 0; i < length; i++) {
            CharType type = toCharType(s.charAt(i));
            if (!transfer.get(state).containsKey(type)) {
                return false;
            } else {
                state = transfer.get(state).get(type);
            }
        }
        return state == State.STATE_INTEGER || state == State.STATE_POINT || state == State.STATE_FRACTION || state == State.STATE_EXP_NUMBER || state == State.STATE_END;
    }

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

    enum State {
        /**
         * 初始状态
         */
        STATE_INITIAL,
        /**
         * 符号
         */
        STATE_INT_SIGN,
        /**
         * 整数部分
         */
        STATE_INTEGER,
        /**
         * 小数点(前面有数字)
         */
        STATE_POINT,
        /**
         * 小数点(前面没数字)
         */
        STATE_POINT_WITHOUT_INT,
        /**
         * 小数部分
         */
        STATE_FRACTION,
        /**
         * e
         */
        STATE_EXP,
        /**
         * 指数符号
         */
        STATE_EXP_SIGN,
        /**
         * 指数
         */
        STATE_EXP_NUMBER,
        /**
         * 终止状态
         */
        STATE_END
    }

    enum CharType {
        /**
         * 数字
         */
        CHAR_NUMBER,
        /**
         * e
         */
        CHAR_EXP,
        /**
         * 小数点
         */
        CHAR_POINT,
        /**
         * 符号
         */
        CHAR_SIGN,
        /**
         * 空格
         */
        CHAR_SPACE,
        /**
         * 非法
         */
        CHAR_ILLEGAL
    }
}
posted @ 2022-01-17 23:31  Tianyiya  阅读(24)  评论(0)    收藏  举报