• 【剑指Offer】53、表示数值的字符串


      题目描述:

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

      解题思路:

      本题相对还是比较简单的,重点在于考虑到所有的情况,能够写出表示数值的字符串模式,然后就可以根据正则表达式或者字符串匹配的相应方法来做。

      表示数值的字符串遵循共同的模式:A[.[B]][e|EC]或者.B[e|EC]

      以上模式的含义是:A为数值的整数部分,B为跟在小数点之后的小数部分,C为跟在e或者E之后的指数部分。其中,A部分可以没有,比如小数.123代表0.123。如果一个数没有整数部分,那么小数部分必须有。

      具体说来,A和C(也就是整数部分和指数部分)都是可能以"+"、"-"开头或者没有符号的数字串,B是数字序列,但前面不能有符号。

      我们可以通过顺序扫描字符串来判断是否符合上述模式,首先尽可能多的扫描数字序列(开头可能有正负号),如果遇到小数点,那么扫描小数部分,遇到e或者E,则开始扫描指数部分。

      除了顺序扫描以外,判断一个字符串是否满足某个模式,我们很容易想到的一个办法是使用正则表达式,以下给出这两种方法代码实现。

      正则表达式的解法很简洁,关于正则表达式的语法参考另外一篇博文:正则表达式

      编程实现(Java):

    public class Solution {
        /*
            思路:表示数字的字符串遵循模式:A[.[B]][e|EC]或者.B[e|EC]
            A为整数部分,B为小数部分,C为指数部分
            开头可能有正负号
            两种方法:逐位判断、正则表达式
         */
        public boolean isNumeric(char[] str) {
            //方法一:逐位判断
            if(str==null)
                return false;
            boolean sign=false,decimal=false,hasE=false; //标记符号、小数点、指数符号E是否出现过
            for(int i=0;i<str.length;i++){
                if(str[i]=='e'||str[i]=='E'){ //有E或者e出现
                    if(i==str.length-1) //E不能是最后一位,后面必须跟指数
                        return false;
                    if(hasE) return false; //E只能出现一次
                    hasE=true;
                }else if(str[i]=='.'){
                    if(hasE||decimal) //指数不能有.小数点只能出现一次 
                        return false;
                    decimal=true;
                }else if(str[i]=='+'||str[i]=='-'){
                    //第一次出现,开头或者e之后
                    if(!sign && i!=0 && str[i-1]!='e' && str[i-1]!='E') //不在开头也不在e之后
                        return false;
                    //第二次出现,E之后
                    if(sign && str[i-1]!='E' && str[i-1]!='e')
                        return false;
                    sign=true;
                }else if(str[i]>'9'||str[i]<'0') //不合法字符
                    return false;
            }
            return true;
        }
        
        //方法二:正则表达式
        //+代表出现一次或多次,*代表出现0次或多次,?代表出现0次或者一次
         public boolean isNumeric(char[] str) {
            String string = String.valueOf(str);
            return string.matches("[\+-]?[0-9]*(\.[0-9]*)?([eE][\+-]?[0-9]+)?");
             /*
             为什么是两个反斜杠
             首先字符串中的\被编译器解释为 -------》  第一步,编译器将字符串转变为“正则表达式”
    		然后作为正则表达式,.又被正则表达式引擎解释为.   ----------------> 第二步,才开始把第一步的结果当做是正则表达式,开始进行匹配!
    		如果在字符串里只写.的话,第一步就被直接解释为.,之后作为正则表达式被解释时就变成匹配任意字符了
             */
        }
    }
    
  • 相关阅读:
    windows 服务实现定时任务调度(Quartz.Net)
    C#编写windows服务,多服务为什么只启动一个(ServiceBase.Run)
    微服务之springCloud-docker-feign(四)
    微服务之springCloud-docker-comsumer(三)
    微服务之springCloud和docker-provide(二)
    docker探索-使用docker service管理swarm(十一 )
    微服务之springCloud和docker-Eureka(一)
    docker打开api remote接口设置
    docker探索-CentOS7中配置Docker的yum源并升级安装docker1.13(十)
    docker探索-docker私有仓库搭建(九)
  • 原文地址:https://www.cnblogs.com/gzshan/p/10880163.html
Copyright © 2020-2023  润新知