剑指Offer_#20_表示数值的字符串

剑指Offer_#20_表示数值的字符串

Contents

题目

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"0123"都表示数值,但"12e"、"1a3.14"、"1.2.3"、"+-5"、"-1E-16"及"12e+5.4"都不是。

思路分析

数字字符串遵循的模式为A[.[B]][e|EC]或者.B[e|EC]
数字字符串当中有两个分界点,

  • 小数点.
  • 指数符号eE

两个分界点,分出了三段数字部分,

  • A是小数点之前的整数部分,可以带有正负号
  • B是小数点之后,指数符号之前的小数部分,不可带有正负号
  • C是指数符号之后的整数部分,可以带有正负号

注意这其中需要特殊考虑的字符就是正负号

算法思路

首先设置几个boolean变量作为flag,用来记录之前是否已经遇到过字符'0'-'9',字符.,字符eE
从前往后遍历字符串,根据当前遇到的字符以及记录下来的flag,判断是否是合法的数字字符串。

解答

class Solution {
    public boolean isNumber(String s) {
        if(s == null || s.length() == 0) return false;
        boolean numSeen = false;
        boolean dotSeen = false;
        boolean eSeen = false;
        char[] str = s.trim().toCharArray();
        for(int i = 0;i < str.length;i++){
            if(str[i] >= '0' && str[i] <= '9'){
                //出现数字'0'~'9',则标记numSeen为true
                numSeen = true;
            }else if(str[i] == '.'){
                //.之前不能出现 . 或者 e
                if(dotSeen || eSeen) return false;
                dotSeen = true;
            }else if(str[i] == 'e' || str[i] == 'E'){
                //e之前不能出现e,且必须出现数字
                if(eSeen || !numSeen) return false;
                eSeen = true;
                //e之后,必须有整数,所以需要把numSeen重置为false
                numSeen = false;
            }else if(str[i] == '-' || str[i] == '+'){
                //正负号只能出现在0位置或者e后面的第一个位置
                if(i != 0 && str[i - 1] != 'e' && str[i - 1] != 'E') return false;
            }else{
                //出现其他字符都是不合法的
                return false;
            }
        }
        //循环到最后一个字符,如果是遇到非法情况,循环未结束就直接返回false了
        //如果循环到最后一个字符,还没有返回false,就判断numSeen是否为true即可
        return numSeen;
    }
}

复杂度分析

时间复杂度:O(n),n为字符串的长度。

猜你喜欢

转载自www.cnblogs.com/Howfars/p/13198121.html