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