每日一题算法:2020年9月2日[表示数值的字符串] isNumber

本文详细解析了一道关于判断字符串是否表示合法数值的算法问题,探讨了正则表达式和逻辑判断的解决方案,并分享了采用台阶模型进行状态转移的解题思路。在实现过程中遇到了空格处理等难点,最终完成了算法的实现。
摘要由CSDN通过智能技术生成

2020年9月2日表示数值的字符串 isNumber

在这里插入图片描述

class Solution {
    public boolean isNumber(String s) {

    }
}

解题思路:

首先,这道题必定会有很多的坑,从这20%的提交成功率上就能看出来,遇到坑没法避免的时候最好的办法就是踩一遍所有坑,踩完就可以顺利通过了。

所以现在我只是针对所有例题中的情况作出通配的计算,其他类型的暂且不管。

进过分析,第一次尝试时将这个字符串表示为

(正负号)数字(小数点)数字(E/e)(正负号)(数字)

先去学习一下正则表达式的用法。

正则表达式学回来了发现,使用正则表达式貌似没有办法解决本题中的问题,或许是我还不知道怎么使用的原因吧。我不知道如何表达,如果存在数字E,那么E后面必须有数字这种情况。

所以还是使用普通的逻辑判断来解决这道问题。

使用普通的逻辑也非常难实现,其中的逻辑非常复杂,很难使用位置来判断是否是合法数字。

在从答案中获得到了灵感,使用这一种新的实现方式。

台阶模型。

把读取这个字符串的过程理解为一个走楼梯的过程,每一层台阶有不同的前进规则。这样解释,当你站在第一层楼梯的时候,你需要读取的字符是“+”,“-”,如果读取到了,或者没有读取到,都走上下一层的台阶。

第二层台阶开始读取数字,规则是只读取数字,如果出现了“.”,则前进一级台阶,如果遇到的是“E”或者是“e”,则前进3个台阶。

当走到楼顶时,如果能够顺利结束最后一个台阶,那么返回true,只要过程中在任何一个台阶上出现了问题,都直接返回false。

???

看了半天没看出哪里有问题,结果发现在尾部插入了一个空格,我人晕了,看来还现需要把空格清零掉,再添加一个台阶来清零空格吧。
在这里插入图片描述

    char[] step;
    int index=0;
    public boolean isNumber(String s) {
        step = s.toCharArray();
        if (step.length==0)
            return false;
        return step0();
    }
    //台阶1,判断是否是符号位
    public boolean step0(){
        if (step[index]=='+'||step[index]=='-')
            index++;
        return step1();
    }
    //台阶2,读取数字
    public boolean step1(){
        //读取数字的长度
        int len=0;
        while (step[index]<=57&&step[index]>=48){
            len++;
            index++;
            //如果台阶2已经到达末尾,返回true
            if (index==step.length)
                return true;
        }
        //如果没有一个数字,存在问题,返回false
        if (len==0)
            return false;

        //如果是小数点,进入台阶3
        if (step[index]=='.')
            return step3();
        //如果是E,进入阶段5
        if (step[index]=='E'||step[index]=='e')
            return step5();

        //如果不是.或者E,那么存在错误,返回false
        return false;
    }
    //台阶3,这个阶段只有一个.
    public boolean step3(){
        //是否已经到达末尾,如果到达末尾返回false,不能以小数点结尾

        if (index+1==step.length)
            return false;
        index++;
        //小数点后必须是数字,进入台阶4
        if (step[index]<=57&&step[index]>=48)
            return step4();
        else
            return false;
    }
    //台阶4,小数点后的数字串
    public boolean step4(){
        //已经测试过存在数字,所以不需要判断没数字的情况
        while (step[index]<=57&&step[index]>=48){
            index++;
            //如果台阶2已经到达末尾,返回true
            if (index==step.length)
                return true;
        }
        //如果是E,进入阶段5,台阶4中的数字结束后必须是E,否则结束
        if (step[index]=='E'||step[index]=='e')
            return step5();
        else
            return false;
    }
    //台阶5,是一个E
    public boolean step5(){
        if (index+1==step.length)
            return false;
        index++;
        //如果是符号,进入台阶6
        if (step[index]=='+'||step[index]=='-')
            return step6();
        //是数字进入台阶7
        else if (step[index]<=57&&step[index]>=48)
            return step7();
        else
            return false;
    }
    //台阶6,是一个符号
    public boolean step6(){
        if (index+1==step.length)
            return false;
        index++;
        if (step[index]<=57&&step[index]>=48)
            return step7();
        else
            return false;
    }
    //台阶顶部,最后一串数字串
    public boolean step7(){
        while (step[index]<=57&&step[index]>=48){
            index++;
            //如果台阶2已经到达末尾,返回true
            if (index==step.length)
                return true;
        }
        return false;
    }

修改2.0版本,增加了空格处理台阶。

啊这。原来还有这种方式表示0.1的吗?长知识了。

这代码太长了,中间修改的版本就不贴了,就贴最后完成的版本吧。
在这里插入图片描述

我是傻逼
在这里插入图片描述

算你厉害,我继续改。
在这里插入图片描述

最终版本:
在这里插入图片描述

class Solution {
    char[] step;
    int index=0;
    public boolean isNumber(String s) {
        step = s.toCharArray();
        if (step.length==0)
            return false;
        return step0();
    }
    //台阶1,判断是否是符号位
    public boolean step0(){
        while (step[index]==' '){
            index++;
            if (index==step.length)
                return false;
        }
        if (step[index]=='+'||step[index]=='-')
            index++;
        return step1();
    }
    //台阶2,读取数字
    public boolean step1(){
        //读取数字的长度
        int len=0;
        while (step[index]<=57&&step[index]>=48){
            len++;
            index++;
            //如果台阶2已经到达末尾,返回true
            if (index==step.length)
                return true;
        }
        //如果没有一个数字,存在问题,返回false
        if (len==0){
            if (step[index]=='.')
                return step3();
            else 
                return false;
        }

        //如果是小数点,进入台阶3
        if (step[index]=='.')
            return step3();
        //如果是E,进入阶段5
        if (step[index]=='E'||step[index]=='e')
            return step5();

        //如果不是进入空格清理
        return step8();
    }
    //台阶3,这个阶段只有一个.
    public boolean step3(){
        //是否已经到达末尾,如果到达末尾返回false,不能以小数点结尾
        if (index+1==step.length){
            //点的前后必须都有数字
            if (index-1>=0&&step[index-1]<=57&&step[index-1]>=48)
                return true;
            else 
                return step8();
        }
            
        index++;
        //小数点后必须是数字,进入台阶4
        if (step[index]<=57&&step[index]>=48)
            return step4();
        //小数点后必须是数字,进入台阶4
        if (step[index]<=57&&step[index]>=48)
            return step4();
            else if (step[index]=='e'||step[index]=='E')
        {
            if (index-2>=0&&step[index-2]<=57&&step[index-2]>=48)
                return step5();
            else 
                return false;
        }
            //如果小数点后不是数字,那么小数点前必须是数字
        else if (index-2>=0&&step[index-2]<=57&&step[index-2]>=48)
        
                return step8();
            else return false;
    }
    //台阶4,小数点后的数字串
    public boolean step4(){
        //已经测试过存在数字,所以不需要判断没数字的情况
        while (step[index]<=57&&step[index]>=48){
            index++;
            //如果台阶2已经到达末尾,返回true
            if (index==step.length)
                return true;
        }
        //如果是E,进入阶段5,台阶4中的数字结束后必须是E,否则结束
        if (step[index]=='E'||step[index]=='e')
            return step5();
        else
            return step8();
    }
    //台阶5,是一个E
    public boolean step5(){
        if (index+1==step.length)
            return false;
        index++;
        //如果是符号,进入台阶6
        if (step[index]=='+'||step[index]=='-')
            return step6();
        //是数字进入台阶7
        else if (step[index]<=57&&step[index]>=48)
            return step7();
        else
            return false;
    }
    //台阶6,是一个符号
    public boolean step6(){
        if (index+1==step.length)
            return false;
        index++;
        if (step[index]<=57&&step[index]>=48)
            return step7();
        else
            return false;
    }
    //台阶顶部,最后一串数字串
    public boolean step7(){
        while (step[index]<=57&&step[index]>=48){
            index++;
            //如果台阶2已经到达末尾,返回true
            if (index==step.length)
                return true;
        }
        return step8();
    }
    //清理空格的台阶
    public boolean step8(){
        while (step[index]==' '){
            index++;
            if (index==step.length)
                return true;
        }
        return false;
    }
}

后话:

今天的算法题感觉很无聊,一开始的时候看到评论说这道题是垃圾题,我还非常不屑,直到我自己因为莫名其妙的原因错了有错之后,我真的觉得这道题没有什么必要,你为什么要在字符串后加空格呢?一共花了我3个小时,其中大多数时间都在测试,修改。一共提交了16次,前面15次都是因为各种原因出错,题目中也没有给出错误样例和正确的样例,以至于测试到后面我都不想贴截图了注释也懒得写。这道题做完之后我肯定能牢牢记住,double类型的字符串输入的正确格式。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值