LeetCode65 有效数字

原题目

验证给定的字符串是否可以解释为十进制数字。
例如:
“0” => true
" 0.1 " => true
“abc” => false
“1 a” => false
“2e10” => true
" -90e3 " => true
" 1e" => false
“e3” => false
" 6e-1" => true
" 99e2.5 " => false
“53.5e93” => true
" --6 " => false
“-+3” => false
“95a54e53” => false
说明: 我们有意将问题陈述地比较模糊。在实现代码之前,你应当事先思考所有可能的情况。这里给出一份可能存在于有效十进制数字中的字符列表:
数字 0-9
指数 - “e”
正/负号 - “+”/"-"
小数点 - “.”
当然,在输入中,这些字符的上下文也很重要。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-number

题目分析

方法一:混乱法:
debug每次将没考虑的情况添上去,最后自己一片混乱。
方法二:直接法:
定个返回标志flag=false,代表遍历到当前位置数字是否有效
一个正确的数字,从开始到结尾的判断如下

条件whileifwhileifwhileif(flag)|(if|while)while
字符空格±数字小数点数字e|(±|数字)空格
flagfalsefalsetrue取决于前面truefalse|false|true取决于前面

return s[i]!=’\0’&&flag=true
方法三:状态机:
将其分为多种状态,默认从状态0开始,利用当前状态和当前字符条件来判断将跳转到下个状态n,将当前状态下,不能继续跳转的字符条件的下一状态设为-1,直接返回false,如果能跳转到最后,判断其是否在几个有效的状态下
在这里插入图片描述

状态\下一状态条件blank(0)±(1)0~9(2)dot(3)e(4)ohter(5)
00132-1-1
1-1-132-1-1
2-1-14-1-1-1
38-1345-1
48-14-15-1
5-167-1-1-1
6-1-17-1-1-1
78-17-1-1-1
88-1-1-1-1-1
状态是否有效012345678
false(0)/true(1)000110011
完整代码

方法一:

bool isNumber(char * s){
    int i=0,j=strlen(s)-1;
    int size_dot=0,site_dot=0;
    int size_e=0,site_e=j+1;
    int size_sum=0;
    while(s[i]==' ')i++;
    if(i>j)return false;
    while(s[j]==' ')j--;
    int left=i,right=j;
    if(i==j&&s[i]>='0'&&s[i]<='9')return true;
    else if(i==j)return false;
    while(i<=j)
    {
        if(s[i]!='+'&&s[i]!='-'&&s[i]!='.'&&s[i]!='e'&&(s[i]<'0'||s[i]>'9'))
        return false;
        else if((s[i]=='+'||s[i]=='-')&&(i!=left&&s[i-1]!='e'||i==right))
        return false;
        else if(s[i]=='.'&&(i!=left&&i!=right&&(s[i-1]<'0'||s[i-1]>'9'||s[i+1]<'0'||s[i+1]>'9')&&(s[i-1]!='+'&&s[i-1]!='-')&&s[i+1]!='e'||i==left&&s[i+1]=='e'))
        {
            return false;
        }
        else if(s[i]=='.')
        {
            size_dot++;
            site_dot=i;
            if(size_dot>1||site_e<site_dot)
                return false;
        }
        else if(s[i]=='e'&&(i==left||i==right||(s[i-1]<'0'||s[i-1]>'9')&&s[i-1]!='.'||((s[i+1]<'0'||s[i+1]>'9')&&s[i+1]!='-'&&s[i+1]!='+')))
        {return false;}
        else if(s[i]=='e')
        {
            size_e++;
            site_e=i;   
            if(size_e>1||site_e<site_dot)
            return false;
        }
        else if(s[i]<='9'&&s[i]>='0')
        {
            size_sum++;
        }
        i++;
    }
    if(size_sum==0)return false;
    return true;
}

方法二:

bool isNumber(char * s){
    int i=0;
    bool flag=false;
    while(s[i]==' ')
    {
        i++;
    }
    if(s[i]=='+'||s[i]=='-')
    {
        i++;
    }
    while(isdigit(s[i]))
    {
        flag=true;
        i++;
    }
    if(s[i]=='.')
    {
        i++;
    }
    while(isdigit(s[i]))
    {
        flag=true;
        i++;
    }
    if(flag==true&&s[i]=='e')
    {
        i++;
        if(s[i]=='+'||s[i]=='-')
        {
            i++;
        }  
        flag=false;
        while(isdigit(s[i]))
        {
            flag=true;
            i++;
        }
    }
    while(s[i]==' ')
    {
        i++;
    }
    return s[i]=='\0'&&flag==true;
}

方法三:

class Solution {
public:
    int fun(char c){
        if(isdigit(c)){
            return 2;
        }
        switch(c){
            case ' ':return 0;
            case '-':return 1;
            case '+':return 1;
            case '.':return 3;
            case 'e':return 4;
            default:return 5;
        }
    }
    bool isNumber(string s) {
        //行:状态0-7 列:下一状态条件:blank,_+,0~9,dot,e,other
        vector<vector<int>>vec={{0,1,3,2,-1,-1},
                                {-1,-1,3,2,-1,-1},
                                {-1,-1,4,-1,-1,-1},
                                {8,-1,3,4,5,-1},
                                {8,-1,4,-1,5,-1},
                                {-1,6,7,-1,-1,-1},
                                {-1,-1,7,-1,-1,-1},
                                {8,-1,7,-1,-1,-1},
                                {8,-1,-1,-1,-1,-1}};
        vector<bool>flag = {0,0,0,1,1,0,0,1,1};
        int j = 0;
        for(auto c : s){
            j = vec[j][fun(c)];
            if(j == -1)return false;
        }
        return flag[j];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Baal Austin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值