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

思路:
【1】感觉常规思路比状态机要好理解,但是状态机怎么说,面试又需要真他妈忧愁
代码展示:
常规的思路解法:
//时间1 ms击败100% //内存41.5 MB击败55.87% class Solution { public boolean isNumber(String s) { // 字符数组 char[] charArray = s.toCharArray(); // 字符串长度 int n = charArray.length; // 当前下标 int index = 0; // 标记 boolean hasNum = false, hasE = false; boolean hasSign = false, hasDot = false; // 将下标移动到非空格字符上 while (index < n && charArray[index] == ' ') { index++; } // 当前下标尚未到达字符串末尾 while (index < n) { // 当前字符 char c = charArray[index]; if (c >= '0' && c <= '9') { // 当前字符是数字 0~9 hasNum = true; } else if (c == 'e' || c == 'E') { // 当前字符是 e / E if (hasE || !hasNum) { // e / E 已经出现过,或者数字没有出现过,则该字符串必定无法表示数值,返回 false return false; } hasE = true; hasNum = false; hasSign = false; hasDot = false; } else if (c == '+' || c == '-') { // 当前字符是正负号 if (hasSign || hasNum || hasDot) { // 如果已经出现过符号、数字、小数点,则该字符串必定无法表示数值,返回 false return false; } hasSign = true; } else if (c == '.') { // 如果是小数点 if (hasDot || hasE) { // 如果已经出现过小数点、e / E ,则该字符串必定无法表示数值,返回 false return false; } hasDot = true; } else if (c == ' ') { // 如果是空格,跳出循环 break; } else { // 非法字符 return false; } // 继续判断下一个字符 index++; } // 如果当前下标尚未到达字符串末尾,则剩下的字符应当全部为空格,否则该字符串必定无法表示数值,返回 false for (; index < n; index++) { if (charArray[index] != ' ') { return false; } } return hasNum; } }
官方的状态机解法:
//时间5 ms击败25.31% //内存41.5 MB击败55.30% class Solution { 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 } }

浙公网安备 33010602011771号