[杨小白]_leetcode_剑指 Offer 20. 表示数值的字符串

102 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情

前言

小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标300题,记录从0到1的全过程!!

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

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

多图预警

image.png

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。

数值(按顺序)可以分成以下几个部分:

  1. 若干空格
  2. 一个 小数 或者 整数
  3. (可选)一个 'e' 或 'E' ,后面跟着一个 整数
  4. 若干空格

小数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符('+' 或 '-')
  2. 下述格式之一:
  • 至少一位数字,后面跟着一个点 '.'
  • 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
  • 一个点 '.' ,后面跟着至少一位数字

整数(按顺序)可以分成以下几个部分:

  1. (可选)一个符号字符('+' 或 '-')
  2. 至少一位数字

部分数值列举如下:

["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"] 部分非数值列举如下:

["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]

示例 1

输入: s = "0"

输出: true

示例 2

输入: s = "e"

输出: false

示例 3

输入: s = "."

输出: false

示例 4

输入: s = " .1 "

输出: true

说明:

  1. S 的长度不超过 50
  2. S 保证为一个满足上述定义的特殊 的二进制序列。
class Solution {
    public boolean isNumber(String s) {
        //除去前后空格
        s = s.trim();
        if(!s.contains("e") && !s.contains("E"))  {
            return isNum(s);
        } else {
            int eindex = Math.max(s.indexOf("e"),s.indexOf("E"));
            return isNum(s.substring(0,eindex)) && isInt(s.substring(eindex + 1, s.length()));
        }
    }
    public boolean isDecimal(String s) {
        int n = s.length();
        if(n==0) return false;
        int i = 0;
        if(s.charAt(i)=='-' || s.charAt(i)=='+') {
            i++;
        }
        if(n-i == 0) return false;
        int index = s.indexOf('.');
        if(index==-1) return false;

        boolean pre = isInt(s.substring(i, index));
        String substring = s.substring(index + 1, n);
        if(substring.contains("+")||substring.contains("-")) return false;
        boolean after = isInt(substring);
        if(!pre &&!after) {
            return false;
        }
        if(pre&&after) return true;
        if(pre) {
            for(int j = index + 1 ; j < s.length(); j++) {
                if(s.charAt(j)<'0' || s.charAt(j) > '9') {
                    return false;
                }
            }
        }
        if(after) {
            for(int j = i; j < index; j++) {
                if(s.charAt(j)<'0' || s.charAt(j) > '9') {
                    return false;
                }
            }
        }
        return true;
    }
    public boolean isNum(String s) {
        return isDecimal(s) || isInt(s);
    }
    public boolean isInt(String s) {
        int n = s.length();
        if(n==0) return false;
        int i = 0;
        if(s.charAt(i)=='-' || s.charAt(i)=='+') {
            i++;
        }
        if(n-i == 0) return false;
        for( ; i < n; i++) {
            if(s.charAt(i)<'0' || s.charAt(i) > '9') {
                return false;
            }
        }
        return true;
    }
}

解析

这个题的测试案例非常的非人哉,这里我给出我几个发生过错误的测试案例:

image.png

image.png

image.png

image.png

image.png

image.png

image.png

从我的提交记录就能看出来,每次都有很多没有考虑的点,每次都不断地打补丁。不够最后两次我全部推翻后重新梳理写的,提交了两次就通过了。

现在经常看别人的代码会把很多代码段提成一个新的功能函数,开始还不理解为什么这么做,因为跳来跳去看的有点头昏,现在自己也习惯了这种写法,这样各个模块功能清晰,每个模块只实现自己的内容即可,耦合度低,自己写的时候也舒服很多。

这个题就是写了两个功能函数,一个是isInt(判断是不是整数)isDecimal(判断是不是小数)isNum是判断(是不是小数或者整数)整整的功能函数还是只有两个。然后根据体艺,分别在两个功能函数中细分判断即可。

3.结束

提交排名如下,也不是很理想哦~

image.png

太菜了,提交好几才才做出来的,前进的道路还很远啊!!!