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

在这里插入图片描述

扫描法

数字格式可以使用 A[.[B]][E|eC]表示A和C都是整数(可以有符号),而B是无符号整数

class Solution {
    /**
    * 由于java基本数据类型只能值传递,所以自定义一个引用类型
    * 该类型保存了需要判别的字符串和一个该字符串的指针
    */
    class IdxString {
        private String s;
        private Integer i;
        public IdxString(String s, Integer i){
            this.s = s;
            this.i = i;
        }
        //指针i++
        public void increaseI(){
            this.i++;
        }
        public String getS(){
            return this.s;
        }
        public Integer getI(){
            return this.i;
        }
        //返回当前指针i处s的字符
        public char charAtI(){
            return this.s.charAt(this.i);
        }
    }

    public boolean isNumber(String s) {
        if(s == null)
            return false;
        s = s.trim();//有"1 ", " 0"的情况直接trim掉
        if(s.length() == 0) return false;//考虑 s 类似" ",只有空格的情况 
        int len = s.length();
        IdxString str = new IdxString(s, 0);
        //先扫描小数点之前是否为数字
        boolean isNumeric = sanInteger(str, len);
        //扫描小数点之后是否为数字
        if(str.getI() < len && str.charAtI() == '.'){
            str.increaseI();//跳过小数点
            //使用 || 的原因: 
            //1、会出现 .123的情况
            //2、会出现 123.的情况
            isNumeric = scanUnsignedInteger(str,len) || isNumeric;
        }
        //扫描e or E 之后是否为数字
        if(str.getI() < len && (str.charAtI() == 'e' || str.charAtI() == 'E')){
            str.increaseI();
            //下面使用 && 是因为:
            // 1、 e|E 前没有数字时不表示数字如 .e1、e1;
            // 2、 e|E 后没有整数时不能表示数字如 12e、12e+5.4
            isNumeric = isNumeric && sanInteger(str, len);
        }
        return isNumeric && str.getI() == len;//只有指针到最底,才代表扫描完毕
    }

    private boolean sanInteger(IdxString str, int len) {
        String s = str.getS();
        Integer i = str.getI();
        if( i < len && (s.charAt(i) == '+' || s.charAt(i) == '-'))
            str.increaseI();
        return scanUnsignedInteger(str, len);
    }

    private boolean scanUnsignedInteger(IdxString str, int len) {
        int before = str.getI();
        while(str.getI() < len && str.charAtI() >='0' && str.charAtI() <= '9'){
            str.increaseI();
        }
        return str.getI() > before;
    }
}
posted @ 2020-08-16 15:34  消灭猕猴桃  阅读(64)  评论(0编辑  收藏  举报