【剑指Offer系列】20-表示数值的字符串(标记法:元素之前互相依赖、互斥)

题目: 表示数值的字符串

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

思路:

  • 任何一个数,末尾一定是数字(直接排除了5e、2.)
  • 是0-9么,是num=true
  • 是"."逗号么,是的话,之前不能出现过逗号(1.2.3),且之前不能e|E(5e+3.2);
  • 是e|E么,是的话,之前不能出现过e|E,且之前必须出现过num数字;
  • 是"+“或者”-"号么,是的话,他们只能出现在i==0即第一个位置,或者出现在e|E 之后(5e+3),出现在别的位置都不可以
  • 除了上述四种情况,都不行
    return true(因为,for循环遍历完都满足)
public class Main20  {
    public static void main(String[] args) {
        List<String> list = Lists.newArrayList("+100","+0.2e+3", "+1+1",".1+1", "5e2", "3.1415926", "-1E-16","2.",".2",".", "12e", "1a3.14", "1.2.3", "+-5");
        Map<Boolean, List<String>> map = list.stream().collect(Collectors.groupingBy(s -> isInt(s.toCharArray())));
        System.out.println(map);
    }

    private static boolean isInt(char[] ch) {
        if (ch == null || ch.length == 0)return false;
        boolean num = false; //字符串中是否出现了整数
        boolean dot = false; //是否出现了逗号
        boolean e = false; //是否出现了e或者E
        //0.末尾只要不是数字,就不可能是数值
        if (ch[ch.length-1] > '9' || ch[ch.length-1] < '0') {
            return false;
        }
        for (int i = 0; i < ch.length; i++) {
            if (ch[i] >= '0' && ch[i] <= '9'){
                num = true;//此时,记录下整数已出现过
            }else if (".".equals(String.valueOf(ch[i]))){//1.逗号之前不能出现过逗号“.”和e|E
                if (dot || e)
                    return false;
                dot = true;//此时,记录下,","号已出现过
            }else if ("e".equalsIgnoreCase(String.valueOf(ch[i]))){//2.e|E之前不能有e|E,且必须有数字
                if (e || !num)
                    return false;
                e = true;//记录下,e或者E已出现过了
            }else if ("-".equals(String.valueOf(ch[i])) || "+".equals(String.valueOf(ch[i]))){//3.+-必须在first或者e|E之后(5e+3)
                if (i != 0 && ! ( "e".equalsIgnoreCase(String.valueOf(ch[i-1])))){//二者均不满足则false
                    return false;
                }
            }else {
                //4.其他符号abc$`/等
                return false;
            }
        }
        // 都满足
        return true;
    }
}

lecode LCR138.有效数字

加了一些边角料补丁

class Solution {
    public boolean validNumber(String s) {
        if (s == null || s.length() == 0) {
            return false;
        }

        if (s.length() == 1) {
            return Character.isDigit(s.charAt(0));
        }
        s = s.trim();
        if (s.length() == 1) {
            return Character.isDigit(s.charAt(0));
        }
        if (s.length() == 0) {
            return false;
        }
        // 最后一位必须为数字(除非是3. 最后一位是逗号)
        char lastChar = s.charAt(s.length() - 1);
        if (!Character.isDigit(lastChar) && !Objects.equals(lastChar, '.')) {
            return false;
        }
        // 防止"+."
        char secChar = s.charAt(s.length() - 2);
        if (Objects.equals(lastChar, '.') && (Objects.equals(secChar, '-') || Objects.equals(secChar, '+'))) {
            return false;
        }
        boolean existNum = false;
        boolean existDot = false;
        boolean existE = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isDigit(c)) {
                existNum = true;
            } else if (Objects.equals('.', c)) {
                if (existDot || existE) {
                    return false;
                }
                existDot = true;
            } else if (Objects.equals('e', c) || Objects.equals('E', c)) {
                if (existE || !existNum || (Objects.equals(s.charAt(i - 1), '0') && i + 1 == s.length())) {
                    return false;
                }
                existE = true;
            } else if (Objects.equals('+', c) || Objects.equals('-', c)) {
                if (i != 0 && !Objects.equals(s.charAt(i - 1), 'e') && !Objects.equals(s.charAt(i - 1), 'E')) {
                    return false;
                }
            } else {
                return false;
            }
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值