• 自动机(java)


    1. 表示数值的字符串

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

    数值(按从左至右的顺序)可以分成以下几个部分:

    • 若干空格
    • 一个 小数 或者 整数
    • (可选)一个 'e' 或 'E' ,后面跟着一个 整数
    • 若干空格

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

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

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

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

    部分数值列举如下:
    ["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]
    部分非数值列举如下:
    ["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]

    输入:s = "0"
    输出:true
    
    输入:s = "e"
    输出:false
    
    输入:s = "."
    输出:false
    
    输入:s = "    .1  "
    输出:true
    


    /**
    状态集合:
    状态0: 只包含起始的空格符(或空)
    状态1: 只包含符号位
    状态2: 只包含整数部分
    状态3: 存在左侧有整数的小数点
    状态4: 存在左侧无整数的小数点
    状态5: 存在小数部分
    状态6: 存在字符e
    状态7: 存在指数部分的符号位
    状态8: 存在指数部分的整数部分
    状态9: 存在末尾的空格符
    
    初始状态:状态0
    接受状态:状态2、3、5、8、9
    
    状态迁移:在状态1接收某些字符迁移到状态2(state1 --(chararters)--> state2)
    0 -> 0, 1, 2, 4  (0 --(空格)--> 0;0 -- (+/-) --> 1; 0 -- ([0-9]) --> 2; 0 -- (.) --> 4)
    1 -> 2, 4
    2 -> 2, 3, 6, 9
    3 -> 5, 6, 9
    4 -> 5
    5 -> 6, 9
    6 -> 7, 8
    7 -> 8
    8 -> 8, 9
    9 -> 9
    **/
    
    import java.util.*;
    class Solution {
        //用枚举变量表示的自动机状态(0-9)
        enum State {
            STATE_INITIAL,
            STATE_INT_SIGN,
            STATE_INTEGER,
            STATE_POINT,
            STATE_POINT_WITHOUT_INT,
            STATE_FRACTION,
            STATE_EXP,
            STATE_EXP_SIGN,
            STATE_EXP_NUMBER,
            STATE_END,
        }
        
        //用枚举变量表示自动机接收的字符类型
        enum CharType {
            CHAR_NUMBER,
            CHAR_EXP,
            CHAR_POINT,
            CHAR_SIGN,
            CHAR_SPACE,
            CHAR_ILLEGAL,
        }
    
        //字符到字符类型的转换
        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;
            }
        }
    
        public boolean isNumeric(String str) {
            //用map表示自动机的迁移关系
            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);
    
            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 = str.length();
            State state = State.STATE_INITIAL;
    
            for (int i = 0; i < length; i++) {
                CharType type = toCharType(str.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;
        }
    }
    
    
  • 相关阅读:
    EasyUI问题小结(不定期更新·······)
    windows服务与前台交互
    C#捕获Windows窗体控件
    C#操作AD域中计算机
    远程桌面 Rdp文件的生成
    正则匹配的例子
    Nodejs中npm install 命令的问题
    Windows下使用curl命令
    关于PostmanURL中不能传递中文的问题
    MyBatis_Study_004(动态代理)
  • 原文地址:https://www.cnblogs.com/bacmive/p/15065967.html
Copyright © 2020-2023  润新知