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

103 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情

1. 题目与解析

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

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

  • 若干空格
  • 一个 小数 或者 整数
  • 一个 'e' 或 'E' ,后面跟着一个 整数(可选)
  • 若干空格(可选)

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

  • 一个符号字符('+' 或 '-')(可选)

  • 下述格式之一:

  • 至少一位数字,后面跟着一个点 '.'

  • 至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字

  • 一个点 '.' ,后面跟着至少一位数字

部分数值列举如下:

["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]

部分非数值列举如下:

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

输入:s = "0"

输出:true

输入:s = "e"

输出:false

输入:s = "."

输出:false

输入:s = "    .1  "

输出:true

读完题目我们就可以知道,本题只要按照题目进行模拟判断即可,但是,如果将所有的条件混在一起判断,会使逻辑的复杂度大大增加,因此,我们可以考虑按照整数,小数以及科学计数法三种情况分类讨论,最后结合在一起判断。

2. 题解

主函数如下所示,首先,为了简单,我们优先将字符串首尾的空格否去除,然后分别判断是否是整数,小数以及科学计数法。

class Solution {
    public boolean isNumber(String s) {
        s = s.trim();
        if (isInt(s) || isFloat(s) || isScience(s)) {
            return true;
        }
        return false;
    } 
}

判断是否为整数的逻辑很简单,首先我们需要判断是否有正负号,如果有的且长度大于1,就跳过这一位开始遍历判断是否全部为数字。

boolean isInt(String s) {
    int index = 0;
    if (s.length() == 0) return false;
    if (s.charAt(0) == '+' || s.charAt(0) == '-') {
        index = 1;
        if (s.length() == 1) {
            return false;
        }
    }
    for (; index < s.length(); index++) {
        char c = s.charAt(index);
        if (c < '0' || c > '9') {
            return false;
        }
    }
    return true;
}

小数的判断逻辑也类似,首先我们需要判断是否有正负号,如果有的且长度大于1,就跳过这一位开始遍历,首先判断是全部为数字,另外,如果有.的话,那就行标记,因为我们只允许一个.存在。

boolean isFloat(String s) {
    boolean dotFlg = true, numFlg = false;
    int index = 0;
    if (s.length() == 0) return false;
    if (s.charAt(0) == '+' || s.charAt(0) == '-') {
        index = 1;
        if (s.length() == 1) {
            return false;
        }
    }
    for (; index < s.length(); index++) {
        char c = s.charAt(index);
        if (dotFlg && c == '.') {
            dotFlg = false;
            continue;
        }
        if (c < '0' || c > '9') {
            return false;
        } else if (!numFlg) {
            numFlg = true;
        }
    }      
    if (numFlg) {
        return true;
    }  
    return false;
}

因为有了前两种判断方法作为工具,科学计数法的判读就简单多了:整数/小数+E/e+整数。

boolean isScience(String s) {
    if (s.length() == 0) return false;
    for (int index = 0; index < s.length(); index++) {
        char c = s.charAt(index);
        if (c == 'e' || c == 'E') {
            if ((isInt(s.substring(0, index)) 
                    || isFloat(s.substring(0, index)))&& 
                isInt(s.substring(index + 1, s.length()))) {
                    return true;
            }
            break;
        }
    }        
    return false;
}