推荐

完整《剑指Offer》算法题解析系列请点击 👉 《剑指Offer》全解析 Java 版

题目描述

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

public class Solution {
   
    public boolean isNumeric(char[] str) {
   
        
    }
}

参考思路①:

考虑所有情况:

  1. 只能有 +,-,E,e,小数点 . ,数字,不能出现其他符号;
  2. +,- 号只能放在首位或者 E,e 后面;
  3. E 或 e 或小数点 . 都只能出现一次;
  4. 在有 E 或 e 的情况下,小数点 . 不能在 E ,e 后面出现;
  5. E ,e 后面必定为数字或 + ,- 号。

参考实现①:

public class Solution {
   
    public boolean isNumeric(char[] str) {
   
        boolean sign = false; //+ - 号是否出现过
        boolean decimal = false; //小数点是否出现过
        boolean hasE = false; // E,e 是否出现过
        
        int len = str.length;
        //遍历字符数组,判断数字是否是数值
        for(int i = 0; i < len; i++) {
   
            if (str[i] == 'E' || str[i] == 'e') {
   
                //如果 E,e 是最后一个字符,则说明E e 后面没有数字了,即说明str不是数值
                if (i == len - 1) {
   
                    return false;
                }
                //只能有一个E或e,如果已经出现过E,e,说明str不是数值
                if (hasE) {
   
                    return false;
                }
                //标记已经有 E 或 e 了。
                hasE = true;
            } else if (str[i] == '+' || str[i] == '-') {
   
                
                if (sign && str[i -1] != 'e' && str[i - 1] != 'E') {
   
                    return false;
                }
                
                if (!sign && i > 0 && str[i - 1] != 'e' && str[i -1] != 'E') {
   
                    return false;
                }
                
                sign = true;
                
            } else if (str[i] == '.') {
   
                if (hasE || decimal) {
   
                    return false;
                }
                decimal = true;
            } else if (str[i] < '0' || str[i] > '9') {
   
                return false;
            }
        }
        return true;
        
    }
}

参考思路②: 正则表达式

正则表达式符号意思:

[]  : 字符集合
()  : 分组
?   : 重复 0 ~ 1 次
+   : 重复 1 ~ n 次
*   : 重复 0 ~ n 次
.   : 任意字符
\\. : 转义后的 .
\\d : 数字

参考实现②:

public class Solution {
   
    public boolean isNumeric(char[] str) {
   
        if (str == null || str.length == 0)
        return false;
    return new String(str).matches("[+-]?\\d*(\\.\\d+)?([eE][+-]?\\d+)?");
    }
}

解释:

[±]? 正负号只能出现 1 次;

*\\d **数字可以出现 0 ~ n 次;

**(\\. \\d +)? **点后面的数字可以出现 1 ~ n 次,但 点后面接数字只能出现一次。(或者说 点 只能出现一次,且后面必须接数字。)

([eE][±]?\\d+)? E 或者 e 后面接 + - 号只能出现 0 ~ 1 次;E 或者 e 后面接了正负号之后可以接 1 ~ n 个数字; E e 接 + - 号,接数字, 这个组合只能出现 0 ~ 1次。

看完之后,如果还有什么不懂的,可以在评论区留言,会及时回答更新。

这里是猿兄,为你分享程序员的世界。

非常感谢各位大佬们能看到这里,如果觉得文章还不错的话, 求点赞👍 求关注💗 求分享👬求评论📝 这些对猿兄来说真的 非常有用!!!

注: 如果猿兄这篇博客有任何错误和建议,欢迎大家留言,不胜感激!