65. 有效数字

题目链接:力扣

 解题思路:从前往后挨个进行有效判断,注意其中e或E和小数点只能出现一次,具体算法如下:

  1. 初始变量:
    1. i =0:遍历指针
    2. dot=false:标记小数点是否已经出现
    3. E = false:标记E是否已经出现
  2. 如果首个字符是符号,则去掉符号位,令i++
  3. 遍历字符串s:
    1. 如果当前字符是小数点:
      1. 如果小数点已经出现过了,返回false,否则令dot=true
      2. 如果e或者E已经出现了,返回false,因为e或E后面只能为整数
      3. 如果小数点后面没有数字,则小数点前面必须有一个数字,否则返回false(小数格式1的要求
      4. 如果小数点前面有数字:
        1. 如果小数点后面是e或E或0-9或者空,continue(小数格式2和3的要求
      5. 如果小数点前面没有数字,则小数点后面必须是0-9,也就是小数点后面不能是e或E或空,(因为小数要么以数字开头,要么小数点开头后面加数字),否则返回false(有效数字组成部分1和2的要求
    2. 否则,如果当前字符是e或E:
      1. 如果e或E已经出现过了或则e后面没有数字,返回false(有效数字组成部分2的要求
      2. e或E前面必须有一个整数或者小数,所以e前面必须为一个数字或者小数点,否则返回false
      3. e或E后面的整数可以带符号,也可以不带符号
        1. 如果带符号,符号后面没有数字了,返回false
        2. 如果符号后面有数字,令i++,消耗掉这个符号
    3. 否则,如果不是数字,直接返回false

AC代码:

class Solution {
    public static boolean isNumber(String s) {
        int i = 0;
        //去掉刚开始的符号位
        if (s.charAt(i) == '+' || s.charAt(i) == '-') {
            i++;
            if (s.length() == 1) {
                return false;
            }
        }
        //标记 '.' 是否出现,点只能出现一次
        boolean dot = false;
        //标记E或e是否出现,也只能出现一次
        boolean E = false;
        for (; i < s.length(); i++) {
            if (s.charAt(i) == '.' && !dot) {//如果是 '.',并且 '.' 还没出现过
                dot = true;
                if (E) {//因为e后面只能是整数,当在e后面出现 '.' 直接返回false
                    return false;
                }

                //如果小数点后面没有数字,则小数点前面必须有一个数字,否则返回false
                if (i + 1 >= s.length() && (i - 1 < 0 || s.charAt(i - 1) < '0' || s.charAt(i - 1) > '9')) {
                    return false;
                }

                //小数点前面有数字
                if (i - 1 >= 0 && s.charAt(i - 1) >= '0' && s.charAt(i - 1) <= '9') {
                    //小数点后面可以是 e或E或 0-9或""
                    if (i + 1 >= s.length() || s.charAt(i + 1) == 'e' || s.charAt(i + 1) == 'E' || s.charAt(i + 1) >= '0' && s.charAt(i + 1) <= '9') {
                        continue;
                    }
                }
                //小数点前面没有数字,则小数点后面必须是0~9之间的一个数,否则返回false
                if (i + 1 >= s.length() || s.charAt(i + 1) < '0' || s.charAt(i + 1) > '9') {
                    return false;
                }
            } else if (s.charAt(i) == '.' && dot) {//小数点只能出现一次,再次出现返回false,不过不加这个判断也能通过测试
                return false;
            } else if (s.charAt(i) == 'e' || s.charAt(i) == 'E') {//当前字符是e或E
                //E或e已经出现了,或者e后面没有整数,返回false
                if (E || i + 1 >= s.length()) {
                    return false;
                }
                E = true;

                //e前面必须有整数或者小数,所以e前面必须为一个数字或者是小数点 否则返回false
                //因为已经做过判断的前面的字符只会包含+,-,0-9和小数点,所以只需要排除+或者-就可以了
                if (i - 1 < 0 || s.charAt(i - 1) == '+' || s.charAt(i - 1) == '-') {
                    return false;
                }

                //e后面的整数可以带符号,也可以不带符号,如果带符号,直接跳过符号位
                if ((s.charAt(i + 1) == '+' || s.charAt(i + 1) == '-')) {
                    if (i + 2 >= s.length()) {//符号位后面没有数字了,返回false
                        return false;
                    }
                    i++;//跳过符号位
                }
            } else if (s.charAt(i) > '9' || s.charAt(i) < '0') {//不是数字,直接返回false
                return false;
            }
        }
        return true;
    }
}

 解法二:正则表达式

AC代码:

class Solution {
    public static boolean isNumber(String s) {
        return s.matches("^[+-]?((\\d+)|(\\d+\\.\\d*)|(\\d*\\.\\d+))([eE][+-]?\\d+)?$");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值