LeetCode 第 65 题(Valid Number)

LeetCode 第 65 题(Valid Number)

Validate if a given string is numeric.

Some examples:
“0” => true
” 0.1 ” => true
“abc” => false
“1 a” => false
“2e10” => true

Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.

这道题是 LeetCode 的提交成功率最低的一道题,Acceptance 只有 12.1%。

其实倒不是这道题有多难,只是要考虑的情况比较多。都考虑清楚了,这道题也就做出来了。

首先呢,输入的字符串的前后可能会有多余的空格。因此第一步预处理就要把多余的空格去掉。下面的代码可以 完成这个功能。

string trim(string s)
{
    string::const_iterator p1 = s.cbegin();
    string::const_iterator p2 = s.cend();

    while(p1 != s.cend())
    {
        if(*p1 != ' ')
        {
            break;
        }
        ++ p1;
    }
    if(p1 == s.cend()) return string();

    while(--p2 != p1)
    {
        if( *p2 != ' ')
        {
            break;
        }
    }

    string ret(p1, ++p2);
    return ret;
}

一个合理的数字要满足些什么条件?我简单的归纳了一下。应该有下面几点。
1.可能出现的字符包括”+-1234567890.eE”,出现其余的字符都说明不是合理的数字表示。
2.“+-”号只能出现在两个地方,字符串的最前面和 “eE” 之后紧贴着“eE”。
3.“.” 只能出现一次,而且“.”的前后必须有一边紧挨着数字。
4.“eE” 也只能出现一次,并且后面要跟着数字,“eE” 的前面只能是数字或“.”。
5.必须要出现数字,也就是 “12345678980” 至少要出来一个。
6.“+-”号后面要跟着数字或“.”。

下面是违反了这 6 条的一些例子:

  • “ABC123” -> 不满足第 1 条。
  • “12-2” -> 不满足第 2 条。
  • “.” -> 不满足第 3 条。
  • “..” -> 不满足第 3 条。
  • “3.e” -> 不满足第 4 条。
  • “3.e.” -> 不满足第 3 条 和 4 条。
  • “” -> 不满足第 5 条。
  • “-5e-” -> 不满足第 6 条。
  • “.1e” -> 不满足第 4 条。

只要满足这 6 条,构成的字符串就是合理的数字表示。下面的代码就能完成对这六条规则的检测。代码不复杂,基本的原理是维护了一个状态机,当遍历完字符串后,如果状态机处在正确的状态上则说明这个字符串是合法的。

bool isNumber(string s)
{
    s = trim(s); // 删除前后多余的空格
    if(s.length() == 0) return false;
    int state = 0; // 0 表示状态不确定  'e' 表示出现了 e , 2 表示是合法的数字
    int dot = 0; // 暂时还没有出现小数点
    int eE = 0; // 暂时还没有出现 e 或 E,所以 eE 的值为 0
    string::const_iterator p = s.cbegin();
    if(*p == '-' || *p == '+') ++p; // +- 号只能出现在两个位置,这是其中之一
    if(*p == '.')
    {
        dot = 1;
        state = '.';// 特殊状态,后面必须有数字
        ++p;
    }
    while(p != s.cend())
    {
        char c = tolower(*p);
        if(state == 'e')
        {
            if(*p == '-' || *p == '+') // 这时 "+-" 号可以出现的另一合法位置
            {
                ++p;
                continue;
            }
        }
        if(isdigit(c))
        {
            state = 2;
            ++ p;
            continue;
        }
        if(c == 'e')
        {
            if(state != 2) return false;// 必须出现在数字或 . 之后
            state = 'e';
            eE ++;
            if(eE > 1) return false;
            ++ p;
            continue;
        }
        if( c == '.')
        {
            if(eE) return false;// . 不能出现在 e 的后面
            state = 2;
            dot ++;
            if(dot > 1) return false;
            ++ p;
            continue;
        }
        else
        {
            return false;
        }
    }
    if(state == 2)
        return true;
    else
        return false;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值