zoukankan      html  css  js  c++  java
  • 【Valid Number】cpp

    题目:

    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.

    代码:

    class Solution {
    public:
        bool isNumber(string s) {
                if ( s.size()<1 ) return false;
                // escape space from begining and end
                int index_begin = 0;
                int index_end = s.size()-1;
                while ( s[index_begin]==' ' && index_begin<s.size() ) ++index_begin;
                while ( s[index_end]==' ' && index_end>=0 ) --index_end;
                // digit, dot, sign, exp
                enum PreChar{ NONPRE, DIGIT, SIGN, EXP, DOT };
                enum PreChar preChar = NONPRE;
                bool hasDigit = false, hasSign = false, hasExp = false, hasDot = false;
                int index = index_begin;
                for ( ;index <= index_end; ++index )
                {
                    // space
                    if ( s[index]==' ') return false;
                    // digit
                    if ( s[index]>='0' && s[index]<='9' ) { hasDigit = true; preChar = DIGIT; continue; }
                    // sign
                    if ( s[index]=='+' || s[index]=='-' ){ 
                        if ( preChar==EXP || preChar==NONPRE ) { preChar = SIGN; hasSign = true; continue; }
                        else { return false; }
                    }
                    // exp
                    if ( s[index]=='e' || s[index]=='E' ){
                        if ( (preChar==DIGIT || preChar==DOT) && !hasExp && hasDigit ) { preChar = EXP; hasExp = true; continue; }
                        else { return false; }
                    }
                    // dot
                    if ( s[index]=='.' ){
                        if ( !hasExp && !hasDot && (preChar==DIGIT || preChar==SIGN || preChar==NONPRE ) ) { preChar = DOT; hasDot = true; continue; }
                        else { return false; }
                    }
                    // illegal input char
                    return false;
                }
                // end with digit or dot
                return preChar==DIGIT || (preChar==DOT && hasDigit);
        }
    };

    tips:

    主要基于这篇blog的思路(http://blog.unieagle.net/2012/11/06/leetcode题目:valid-number/)。在其基础上,对逻辑进行了更系统的梳理和简化。

    思路如下:

    1. 首先排除字符串首尾的space,这样可以简化判断逻辑(只要在后面的字符串中再出现空格,就一定不是合法数字)

    2. 判断剩余的字符串中出现dot('.'), sign('+','-'), exp('e','E'), digit(0~9)是否是合法的。判断的核心逻辑有两个:

      a. 上一个出现的字符是什么(即代码中的preChar)

      b. dot,sign,exp,digit,是否在之前出现过

    这种代码逻辑的好处是:只要认准了两个核心判断逻辑,在这两个核心逻辑之内修修补补,就可以不断地刷test case直到AC。

    如果以后有类似的问题,状态条件非常多的,但是输入条件相对固定;并且又需要根据序列化输入条件判断的。

    可以多设定几类变量逻辑变量,然后通过判断几类逻辑变量的取值来往下进行;即使不能一次bug free,但是总可以把逻辑补完全。

    =====================================================

    之前一直看网上的有限状态机(FSM)的做法(http://www.cnblogs.com/chasuner/p/validNumber.html),这种思路的代码非常consice。

    FSM怎么运转的,解释的很清晰;但是FSM中这0~8的状态是怎么来的,我并没有看懂,所以只好选择比较一般的方法。

    ================================================

    第二次过这道题,直接照着上次写的代码记忆重复了一下。

    class Solution {
    public:
        bool isNumber(string s) {
                if ( s.size()<1 ) return false;
                // remove blanks both begin and end
                int i_begin = 0;
                int i_end = s.size()-1;
                while ( s[i_begin]==' ' && i_begin<i_end ) ++i_begin;
                while ( s[i_end]==' ' && i_begin<i_end ) --i_end;
                enum PreType{ NONE, DIGIT, EXP, SIGN, DOT };
                enum PreType preType = NONE;
                bool hasDigit=false, hasExp=false, hasSign=false, hasDot=false;
                int i = i_begin;
                for ( ;i<=i_end; ++i )
                {
                    // blank
                    if ( s[i]==' ' )
                    {
                        return false;
                    }
                    // digit
                    else if ( s[i]>='0' && s[i]<='9' )
                    {
                        hasDigit = true; preType = DIGIT;
                    }
                    // sign
                    else if ( s[i]=='+' || s[i]=='-' )
                    {
                        if ( preType==EXP || preType==NONE )
                        {
                            hasSign=true; preType = SIGN;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    // exp
                    else if ( s[i]=='e' || s[i]=='E' )
                    {
                        if ( (preType==DIGIT || preType==DOT) && !hasExp && hasDigit )
                        {
                            hasExp=true; preType=EXP;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    // dot
                    else if ( s[i]=='.' )
                    {
                        if( !hasExp && !hasDot && (preType==DIGIT || preType==SIGN || preType==NONE ) )
                        {
                            hasDot=true; preType = DOT;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        return false;
                    }
                }
                return preType==DIGIT || (preType==DOT && hasDigit);
        }
    };
  • 相关阅读:
    LeetCode题解(14)--Longest Common Prefix
    LeetCode题解(12)--Integer to Roman
    LeetCode题解(13)--Roman to Integer
    LeetCode题解(9)--Palindrome Number
    LeetCode题解(8)--String to Integer (atoi)
    LeetCode题解(7)--Reverse Integer
    LeetCode题解(6)--ZigZag Conversion
    从并发和索引说说innodb和myisam的区别
    thrift基本概念和实例
    fastcgi+lighttpd+c语言 实现搜索输入提示
  • 原文地址:https://www.cnblogs.com/xbf9xbf/p/4494135.html
Copyright © 2011-2022 走看看