剑指Offer-19表示数值的字符串

public static boolean isNumber(String s) {
    s = s.trim();
    try {
        Double.parseDouble(s);
    }catch (NumberFormatException e){
        return false;
    }
    // 排除特殊情况
    char last = s.charAt(s.length()-1);
    return (last >= '0' && last <= '9') || last == '.';
}

为了通过面试 当然不能这么写哈哈哈

思路是有限状态自动机!按照字符串从左到右的顺序,定义以下 9 种状态。

0.开始的空格
1.幂符号前的正负号
2.小数点前的数字
3.小数点、小数点后的数字
4.当小数点前为空格时,小数点、小数点后的数字
5.幂符号
6.幂符号后的正负号
7.幂符号后的数字
8.结尾的空格

理解透了 代码其实很简单

public static boolean isNumber(String s) {
    // 主要就是把有限状态自动机画出来
    Map[] states = {
            new HashMap<Character, Integer>() {{ put(' ', 0); put('s', 1); put('d', 2); put('.', 4); }},
            new HashMap<Character, Integer>() {{ put('d', 2); put('.', 4); }},
            new HashMap<Character, Integer>() {{ put('d', 2); put('.', 3); put('e', 5); put(' ', 8); }},
            new HashMap<Character, Integer>() {{ put('d', 3); put('e', 5); put(' ', 8); }},
            new HashMap<Character, Integer>() {{ put('d', 3); }},
            new HashMap<Character, Integer>() {{ put('s', 6); put('d', 7); }},
            new HashMap<Character, Integer>() {{ put('d', 7); }},
            new HashMap<Character, Integer>() {{ put('d', 7); put(' ', 8); }},
            new HashMap<Character, Integer>() {{ put(' ', 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);
    }
    // 合法的结束状态有 2, 3, 7, 8
    return p == 2 || p == 3 || p == 7 || p == 8;
}

下面这个思路也太棒了吧 而且很好理解

public static boolean isNumber(String s) {
    if (s == null || s.length() == 0){
        return false;
    }
    //去掉头尾空格
    s = s.trim();
    boolean numFlag = false;
    boolean dotFlag = false;
    boolean eFlag = false;
    for (int i = 0; i < s.length(); i++) {
        //判定为数字,则标记numFlag
        if (s.charAt(i) >= '0' && s.charAt(i) <= '9') {
            numFlag = true;
            //判定为.  需要没出现过.并且没出现过e
        } else if (s.charAt(i) == '.' && !dotFlag && !eFlag) {
            dotFlag = true;
            //判定为e,需要没出现过e,并且出过数字了
        } else if ((s.charAt(i) == 'e' || s.charAt(i) == 'E') && !eFlag && numFlag) {
            eFlag = true;
            numFlag = false;//为了避免123e这种请求,出现e之后就标志为false
            //判定为+-符号,只能出现在第一位或者紧接e后面
        } else if ((s.charAt(i) == '+' || s.charAt(i) == '-') && (i == 0 || s.charAt(i - 1) == 'e' || s.charAt(i - 1) == 'E')) {

            //其他情况,都是非法的
        } else {
            return false;
        }
    }
    return numFlag;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值