算法练习-表示数值的字符串

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

题目描述

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

 

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

这道题在官方的解题思路用的是确定有限状态自动机来实现,这个没有汇编这方面的前置知识很难想到,所以这里我就用了另外的一种方法。

首先,我们先分析一下这些正确数字和错误数字的正确原因和错误原因

123,0123,456 : 正确,纯数字

+100,-100:正确,1+123,"+ -5":错误
数字前面有加号或减号时, 加号和减号前没有数字和其他符号

“5e2”,"-1E-16":正确, “1a3.14”,“12e+5.4”,“12e”:错误
e/E是科学计数法,表示的是10的多少次方,例如5e2就是5乘以10的2次方
在上面的例子中可以知道:(1)数字中可以有字母e/E,但是其他字母不行.(2)e前e后必有数,但是必须为整数

“3.1416”,“0.67”:正确,“1.2.3”,".23","“23.”":错误
小数点可以出现在数字之间,但是只能出现一次

从上面的例子分析,我们可以了解到:
(1) 单纯的数字时正确的
(2)加减号要出现在数字前而且不能连续
(3)小数点只能出现在数字之间,而且只能出现一次
(4)数字中可以有字母e/E,但是其他字母不行
(5)e前e后必有数,但是必须为整数

根据上面得出的结论中,我们划分为3种状态,只有这4个状态都符合了就是数字字符串.

  1. 数字位置: 任意
  2. 加减号位置:只能在数字之前,必须是在第一个字符的位置,但是除了出现e的情况
  3. e/E的位置:e前后必须有数,带正负号都可以,但不能出现小数点
  4. 小数点的位置:只能出现一次,小数点前后都有数

因此我们根据上面的分析结论,对一个字符串中的字符进行遍历,对其中的字符进行判断,同时用numSeen (记录是否有了数字的情况),dotSeen (是否有了小数点的情况),eSeen (是否有了e/E的情况)同时判断数字是否成立的情况.

代码

//code
public boolean isNumber(String s) {
        if(s == null || s.length() == 0){
            return false;
        }
        //标记是否遇到相应情况
        boolean numSeen = false;
        boolean dotSeen = false;
        boolean eSeen = false;
        char[] str = s.trim().toCharArray();
        for(int i = 0;i < str.length; i++){
            if(str[i] >= '0' && str[i] <= '9'){
                numSeen = true;
            }else if(str[i] == '.'){
                //.之前不能出现.或者e
                if(dotSeen || eSeen){
                    return false;
                }
                dotSeen = true;
            }else if(str[i] == 'e' || str[i] == 'E'){
                //e之前不能出现e,必须出现数
                if(eSeen || !numSeen){
                    return false;
                }
                eSeen = true;
                numSeen = false;//重置numSeen,排除123e或者123e+的情况,确保e之后也出现数
            }else if(str[i] == '-' || str[i] == '+'){
                //+-出现在0位置或者e/E的后面第一个位置才是合法的
                if(i != 0 && str[i-1] != 'e' && str[i-1] != 'E'){
                    return false;
                }
            }else{//其他不合法字符
                return false;
            }
        }
        return numSeen;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值