Sword20——表示数值的字符串

Sword20——表示数值的字符串

方法1——有限状态交换机

  • 思路:
    • 首先确定所有可能的状态
      • 1——起始空格——State.STATE_INITIAL
      • 2——符号——State.STATE_INT_SIGN
      • 3——小数点前的数字(整数部分)——State.STATE_INTEGER
      • 4——左侧有整数的小数点——State.STATE_POINT
      • 5——左侧无小数的小数点——State.STATE_POINT_WITHOUT_INT
      • 6——小数点后的数字——State.STATE_FRACTION
      • 7——幂字符e——State.STATE_EXP
      • 8——幂字符指数的符号——State.STATE_EXP_SIGN
      • 9——幂字符指数的数字——State.STATE_EXP_NUMBER
      • 10——末尾空格——State.STATE_END
    • 其次确定字符串中字符的可能类型
      • 1——数值型——CHAR_NUMBER
      • 2——幂字符e——CHAR_EXP
      • 3——小数点——CHAR_POINT
      • 4——符号——CHAR_SIGN
      • 5——空格——CHAR_SPACE
      • 6——非法字符——CHAR_ILLEGAL
    • 再确定正确的状态
      • 3——此数为整数,如整数格式“+100”、“-123”、“0123”
      • 4——此数为小数点左侧有整数的小数,如小数第一格式“1.”
      • 6——此数为小数点左侧无整数的小数,如小数第三格式“.1”
      • 9——此数为幂指数,如带幂次方格式“5e2”、“-1E-16”
      • 10——完整数,如小数第二格式“3.1416”

状态转移过程

  • 特殊情况与临界分析:字符串中间出现了非法字符,可直接返回
  • 终止条件:字符串遍历完时,交换机是否为可接受的状态
  • 步骤:
    • 构造transfer数组,其中存储十个Map
      • 每个Map分别保存当前状态,可通过指定字符类型,移动到可达的下一个状态
      • 其中Key为指定字符类型,Value为通过指定字符类型可到达的下一状态
    • 从初始状态开始进行
    • for循环遍历字符串
      • 获取当前字符的类型
      • 根据字符类型,判断当前字符类型是否位于transfer数组当前状态可达的下一状态
        • 不位于,则返回false
        • 位于,则更改为下一状态
    • 判断最终到达的状态,是否为交换机可接受的终止状态
    • 获取当前字符的类型方法
      • 确定ch为数字
      • 确定ch为幂字符e或E
      • 确定ch为小数点
      • 确定ch为符号
      • 确定ch为空格
      • 确定ch为非法字符
public boolean isNumber(String s) {
    // 构造transfer数组,其中存储十个Map
    // 每个Map分别保存当前状态,可通过指定字符类型,移动到可达的下一个状态
    // 其中Key为指定字符类型,Value为通过指定字符类型可到达的下一状态
    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 = s.length();
    // 从初始状态开始
    State state = State.STATE_INITIAL;

    // 对字符串进行遍历
    for (int i = 0; i < length; i++) {
        // 判断当前字符的类型
        CharType type = toCharType(s.charAt(i));
        // 根据字符类型,判断当前字符类型是否位于transfer数组当前状态可达的下一状态
        if (!transfer.get(state).containsKey(type)) {
            // 如果不位于,则返回false
            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) {
    // 确定ch为数字
    if (ch >= '0' && ch <= '9') {
        return CharType.CHAR_NUMBER;
    // 确定ch为幂字符e或E
    } else if (ch == 'e' || ch == 'E') {
        return CharType.CHAR_EXP;
    // 确定ch为小数点
    } else if (ch == '.') {
        return CharType.CHAR_POINT;
    // 确定ch为符号
    } else if (ch == '+' || ch == '-') {
        return CharType.CHAR_SIGN;
    // 确定ch为空格
    } else if (ch == ' ') {
        return CharType.CHAR_SPACE;
    // 确定ch为非法字符
    } else {
        return CharType.CHAR_ILLEGAL;
    }
}

// 枚举十种状态
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
}

方法1——有限状态交换机

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值