表示数值的字符串 Java求解,耗时4s,优于有限状态机的暴力求解法

目录

题目

解题思路

代码


题目

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

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

若干空格
一个 小数 或者 整数
(可选)一个 'e' 或 'E' ,后面跟着一个 整数
若干空格
小数(按顺序)可以分成以下几个部分:

(可选)一个符号字符('+' 或 '-')
下述格式之一:
至少一位数字,后面跟着一个点 '.'
至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
一个点 '.' ,后面跟着至少一位数字
整数(按顺序)可以分成以下几个部分:

(可选)一个符号字符('+' 或 '-')
至少一位数字
部分数值列举如下:

["+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

示例 5:

输入:s = "    .1.  "
输出:false

示例 6:

输入:s = "    6+1  "
输出:false

提示:

1 <= s.length <= 20
s 仅含英文字母(大写和小写),数字(0-9),加号 '+' ,减号 '-' ,空格 ' ' 或者点 '.' 。

解题思路

第一步:预处理,删除掉字符串前后空格。纯空格返回false
第二步:遍历字符串,根据字符进行判断,如果满足条件则继续循环,不满足则中断,return false
根据字符判断
满足以下则继续循环,不满足则return false
1.符号位:后跟数字或小数点,前一位为数字或没有前一位
2.数字:任何情况均满足,无需判断
3.小数点:小数点之前没出现过,e或E之前没出现过,前一位为数字或后一位为数字
4.e或E:非字符串首位,e或E之前没出现过,后跟符号位或数字
5.其他输入:return false

时间复杂度O(n) 空间复杂度O(1)

代码

    public boolean isNumber(String s) {

        //预处理:删除掉数值前后空格
        int indexBefore = 0;
        int indexAfter = s.length() - 1;
        while (indexAfter >= 0 && s.charAt(indexAfter) == ' ') {
            indexAfter--;
        }
        //当字符串只有空格时
        if (indexAfter == -1) {
            return false;
        }
        while (indexBefore < s.length() && s.charAt(indexBefore) == ' ') {
            indexBefore++;
        }
        s = s.substring(indexBefore, indexAfter + 1);
        System.out.println(s);
        //--------判断是否为数值---------
        //可为小数标识或是没有e标识(e或E之后不能有小数)
        boolean canXiaoshu = true;
        //小数点已经出现了吗?
        boolean point=false;
        for (int i = 0; i < s.length(); i++) {
            CharType c = toCharType(s.charAt(i));
            //字符为符号+、-
            if (c == CharType.CHAR_SIGN) {
                //不满足以下四种情况,即中断(不限制前一位会出现6+1错误)
                //1.后一位为数字且是字符串首位
                //2.后一位为.且是字符串首位
                //3.后一位为数字且前一位为e或E
                //4.后一位为.且前一位为e或E
                if (!(i < s.length() - 1 && (toCharType(s.charAt(i+1))==CharType.CHAR_NUMBER
                                              || toCharType(s.charAt(i+1)) == CharType.CHAR_POINT)
                        &&(i==0||(i>0&&toCharType(s.charAt(i-1))==CharType.CHAR_EXP))
                )) {
                    return false;
                }
            }
            //字符是数字,任何情况下都对
            else if (c==CharType.CHAR_NUMBER) {
            }
            //字符是.
            else if (c == CharType.CHAR_POINT) {
                //不满足以下两种情况,即中断(不限制点是否出现过会出现.1.错误)
                //1.e没出现过且点.没出现过且前一位为数字
                //2.e没出现过且点.没出现过且后一位为数字
                if (!(canXiaoshu && !point &&
                        ((i > 0 && toCharType(s.charAt(i-1))==CharType.CHAR_NUMBER)
                                || (i < s.length() - 1 && toCharType(s.charAt(i+1))==CharType.CHAR_NUMBER)
                        )
                )
                ) {
                    return false;
                }else {
                    //设置点已经出现,限制小数
                    point=true;
                }
            }
            //字符是e或E
            else if (c == CharType.CHAR_EXP) {
                //不满足以下两种情况,即中断
                //非字符串首位,e没出现过,后一位为符号位(+或-)
                //非字符串首位,e没出现过,后一位为数字
                if (!(canXiaoshu && i > 0 && i < s.length() - 1
                        && (toCharType(s.charAt(i+1))==CharType.CHAR_NUMBER
                        || toCharType(s.charAt(i+1))==CharType.CHAR_SIGN
                )
                )
                ) {
                    return false;
                } else {
                    //设置e已经出现,限制小数
                    canXiaoshu = false;
                }
            } else {
                return false;
            }
        }
        return true;
    }
    enum CharType {
        CHAR_NUMBER,//数字
        CHAR_EXP,//e/E
        CHAR_POINT,//.
        CHAR_SIGN,//+/-
        CHAR_ILLEGAL//其他非法输入
    }
    public CharType toCharType(char ch) {
        if (ch >= '0' && ch <= '9') {
            return CharType.CHAR_NUMBER;
        } else if (ch == 'e' || ch == 'E') {
            return CharType.CHAR_EXP;
        } else if (ch == '.') {
            return CharType.CHAR_POINT;
        } else if (ch == '+' || ch == '-') {
            return CharType.CHAR_SIGN;
        } else {
            return CharType.CHAR_ILLEGAL;
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值