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

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

模拟

class Solution {
    public boolean isNumber(String s) {
        boolean isNum = false, isDot = false, isE = false;  // 标记是否遇到数位、小数点、'e'或'E'
        char[] ch = s.trim().toCharArray();  // 删除字符串头尾的空格,转为字符数组,方便遍历判断每个字符
        for(int i = 0; i < ch.length; i++){
            char c = ch[i];
            if(c >= '0' && c <= '9') isNum = true;  // 判断当前字符是否为 0~9 的数位
            else if(c == '.'){
                if(isDot || isE) return false;  // 小数点之前可以没有整数,但是不能重复出现小数点、或出现'e'或'E'
                isDot = true;  // 标记已经遇到小数点
            }else if(c == 'e' || c == 'E'){  // 遇到'e'或'E'
                if(isE || !isNum) return false;  // 'e'或'E'前面必须有整数,且前面不能重复出现'e'或'E'
                isE = true;  // 标记已经遇到'e'或'E'
                isNum = false;  // 重置isNum,因为'e'或'E'之后也必须接上整数,防止出现 123e或者123e+的非法情况
            }else if(c == '-' || c =='+'){
                if(i != 0 && ch[i - 1] != 'e' && ch[i - 1] != 'E') return false;  // 正负号只可能出现在第一个位置,或者出现在'e'或'E'的后面一个位置
            }else return false;  // 其它情况均为不合法字符
        }
        return isNum;  // 最后返回是否是数字
    }
}

有限状态自动机

class Solution {
    HashMap<Character, Integer>[] map = new HashMap[10];
    void init(){
        map[0] = new HashMap<Character, Integer>();
        map[0].put(' ', 0);
        map[0].put('s', 1);
        map[0].put('d', 2);
        map[0].put('.', 9);

        map[1] = new HashMap<Character, Integer>();
        map[1].put('d', 2);
        map[1].put('.', 9);

        map[2] = new HashMap<Character, Integer>();
        map[2].put('d', 2);
        map[2].put('.', 3);
        map[2].put(' ', 8);
        map[2].put('e', 5);

        map[3] = new HashMap<Character, Integer>();
        map[3].put('d', 4);
        map[3].put(' ', 8);
        map[3].put('e', 5);

        map[4] = new HashMap<Character, Integer>();
        map[4].put('d', 4);
        map[4].put('e', 5);
        map[4].put(' ', 8);

        map[5] = new HashMap<Character, Integer>();
        map[5].put('s', 6);
        map[5].put('d', 7);

        map[6] = new HashMap<Character, Integer>();
        map[6].put('d', 7);

        map[7] = new HashMap<Character, Integer>();
        map[7].put('d', 7);
        map[7].put(' ', 8);

        map[8] = new HashMap<Character, Integer>();
        map[8].put(' ', 8);

        map[9] = new HashMap<Character, Integer>();
        map[9].put('d', 4);
    }

    public boolean isNumber(String s) {
        init();
        int p = 0;
        char t;
        HashSet<Integer> end = new HashSet<>(Arrays.asList(2, 3, 4, 7, 8));
        for(char c : s.toCharArray()){
            if(c == ' '){
                p = map[p].getOrDefault(c, -1);
            }else if(c == '+' || c == '-'){
                p = map[p].getOrDefault('s', -1);
            }else if(c >= '0' && c <= '9'){
                p = map[p].getOrDefault('d', -1);
            }else if(c == 'e' || c == 'E'){
                p = map[p].getOrDefault('e', -1);
            }else if(c == '.'){
                p = map[p].getOrDefault('.', -1);
            }else return false;
            if(p == -1) return false;
        }
        return end.contains(p);
    }
}

简洁写法

class Solution {
    public boolean isNumber(String s) {
        Map[] states = {
            new HashMap<>() {{ put(' ', 0); put('s', 1); put('d', 2); put('.', 4); }}, // 0.
            new HashMap<>() {{ put('d', 2); put('.', 4); }},                           // 1.
            new HashMap<>() {{ put('d', 2); put('.', 3); put('e', 5); put(' ', 8); }}, // 2.
            new HashMap<>() {{ put('d', 3); put('e', 5); put(' ', 8); }},              // 3.
            new HashMap<>() {{ put('d', 3); }},                                        // 4.
            new HashMap<>() {{ put('s', 6); put('d', 7); }},                           // 5.
            new HashMap<>() {{ put('d', 7); }},                                        // 6.
            new HashMap<>() {{ put('d', 7); put(' ', 8); }},                           // 7.
            new HashMap<>() {{ put(' ', 8); }}                                         // 8.
        };
        int p = 0;
        char t;
        for(char c : s.toCharArray()) {
            if(c >= '0' && c <= '9') t = 'd';
            else if(c == '+' || c == '-') t = 's';
            else if(c == 'e' || c == 'E') t = 'e';
            else if(c == '.' || c == ' ') t = c;
            else t = '?';
            if(!states[p].containsKey(t)) return false;
            p = (int)states[p].get(t);
        }
        return p == 2 || p == 3 || p == 7 || p == 8;
    }
}

你可能感兴趣的:(#,剑指offer,算法)