表示数值的字符串

剑指OFFER题35------按牛客网通过率排序

时间:2018.12.29.1040
作者:Waitt

题目

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

时间限制:1秒 空间限制:32768K 热度指数:104555

解答

思路1

可将一个数分为两部分,E之前E之后
E之前: 正负号仅能出现在首位,0-9可以出现在任何位置,‘.’出现在首位、正负号以及数字之后且仅能出现一次,并且‘.’之后只能接0-9。
E之后: 正负号可以紧接着E出现,其余均为0-9。
特殊情况: E不可出现在首位或末位。

设置4个判断位:符号:f、 点:d、 E/e:e、 数字:s

E之前可分为首位判断与其它位判断
首位判断:可以出现‘+’、‘-’、‘.’、‘0-9’,其余情况均为FALSE。
情况1:仅出现过符号位,则此位可为:‘.’、‘0-9’。(仅首位有可能出现正负号,其余位置均不可能)
情况2:小数点刚出现,后仅可接数字
情况3:小数点已出现,并且上一位是数字,后可接数字和E
情况4:出现的全是数字,后可跟小数点,数字,以及E。

特殊情况: E不可出现在末位。

E之后
紧接着的第一个可以出现符号位,其余均为数字。

class Solution {
public:
    bool isNumeric(char* string)
    {
        int i=0,j=0;//i为数组长度,j为位数
        bool f=0,d=0,e=0,s=0;//符号:f、	点:d、	E/e:e、	数字:s
        i=strlen(string);//数组长度
        if(j>=i)
            return 0;
        while(j<i&&e==0)//E前判断
        {
            if(j==0)//首位判断
            {
                if(*string==43||*string==45||*string==46||(*string>=48&&*string<=57))
                {
                    if(*string==43||*string==45)//符号位判断
                        f=1;
                    else if(*string==46)//小数点判断
                        d=1;
                    else //数字判断
                        s=1;
                    j++;
                    string++;
                    continue;
                }
                return 0;//其余情况为FALSE
            }
            if(f==1&&d==0&&s==0)//仅出现符号位
            {
                if(*string==46||(*string>=48&&*string<=57))
                {
                    if(*string==46)//小数点判断
                        d=1;
                    else//数字判断
                        s=1;
                    j++;
                    string++;
                    continue;
                }
                return 0;//其余情况为FALSE
            }
            if(d==1&&s==0)//小数点刚出现
            {
                if(*string>=48&&*string<=57)
                {
                    s=1;
                    j++;
                    string++;
                    continue;
                }
                return 0;
            }
            else if(d==1&&s==1)//小数点已出现,并且上一位为数字
            {
                if(*string==69||*string==101||(*string>=48&&*string<=57))
                {
                    if(*string==69||*string==101)//E判断
                    {
                        s=0;
                        e=1;
                    }
                    j++;
                    string++;
                    continue;
                }
                return 0;
            }
            if(s==1&&d==0)//出现的全为数字
            {
                if(*string==46||*string=='E'||*string==101||(*string>=48&&*string<=57))
                {
                    if(*string==46)//小数点出现判断
                    {
                        d=1;
                        s=0;
                    }
                    if(*string=='E'||*string==101)//E判断
                    {
                        s=0;
                        f=0;
                        e=1;
                    }
                    j++;
                    string++;
                    continue;
                }
                return 0;
            }
        }
        if(j==i&&e==1)//E末位判断
            return 0;
        while(j<i&&e==1)//E后判断
        {
            if(s==0&&f==0)//E后首位判断
            {
                if(*string==43||*string==45||(*string>=48&&*string<=57))
                    {
                        if(*string==43||*string==45)
                            f=1;
                        else 
                            s=1;
                        j++;
                        string++;
                        continue;
                    }
                return 0;
            }
            if(f==1||s==1)//其它位判断
            {
                if(*string>=48&&*string<=57)
                {
                    j++;
                    string++;
                    continue;
                }
                return 0;
            }
        }
        return 1;
           
    }

};
思路2

将所有的特殊情况均进行判断,其余情况均为TRUE

  1. 对字符串中的每个字符进行判断分析
  2. e(E)后面只能接数字,并且不能出现2次,并且前一位不能为正负号
  3. 对于+、-号,只能出现在第一个字符或者是e的后一位,且不能为最后一位
  4. 对于小数点,不能出现2次,e后面不能出现小数点,并且’.'的前一位或后一位一定得是数字
class Solution {
public:
    bool isNumeric(char* string)
    {
        int i=0,n=strlen(string);
        bool d=0,f=0,e=0;//小数点:d、符号:f、E/e:e
        for(;i<n;i++)
        {
            if(string[i]=='+'||string[i]=='-')//符号位判断
            {
                if(i!=0&&(string[i-1]!='E'&&string[i-1]!='e'))
                    return 0;
                if(i==n-1)
                    return 0;
            }
            else if(string[i]=='.')//小数点判断
            {
                if(e==1||d==1)
                    return 0;
                if(!((string[i-1]>='0'&&string[i-1]<='9')||(string[i+1]>='0'&&string[i+1]<='9')))
                    return 0;
                d=1;
            }
            else if(string[i]=='E'||string[i]=='e')//E判断
            {
                if(i==n-1||e==1)
                    return 0;
                if(string[i-1]=='+'||string[i-1]=='-')
                    return 0;
                e=1;
            }
            else if(string[i]<'0'||string[i]>'9')//其他位置判断
                return 0;
        }
        return 1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值