LeetCode Valid Number

class Solution {
public:
    // a valid number should be in the below form
    // -/+digit.digitE/e+/-digit
    bool isNumber(const char *s) {
        if (s == NULL) return false;
        int end = 0;
        while (s[end] != '\0') end++;
        while (s[--end] == ' ');
        end++;
        // 0-initial, 1-sign-collected, 2-integer_part digit collected, 3-float_point collected,
        // 4-fraction part digit collected, 5-e/E collected, 6-sign of E collected, 7-digit of E collected,
        // 8-mid_space
        int stage = 0; 
        int pos = 0;
        char ch = '\0';
        
        int stages = 0;;

        while ((ch = s[pos]) != '\0' && pos < end) {
            switch(stage) {
                case 0: // initial
                    if (ch == ' ') {
                        // white spaces, just skip
                        pos++;
                    } else if (ch == '+' || ch == '-') {
                        // sign found
                        stage = 1;
                        pos++;
                    } else if (ch == '.') {
                        // float point found
                        stage = 3;
                        pos++;
                    } else if (ch >= '0' && ch <= '9') {
                        // digit found
                        stage = 2;
                    } else {
                        // the other chars are invalid in [initial stage]
                        return false;
                    }
                    break;
                case 1: // sign collected
                    stages |= 1<<(stage - 1);
                    if (ch >= '0' && ch <= '9') {
                        // digit found
                        stage = 2;
                    } else if (ch == '.') {
                        // float point found
                        stage = 3;
                        pos++;
                    } else {
                        // the other chars are invalid in [sign collected stage]
                        return false;
                    }
                    break;
                case 2: // integer part digit collected
                    stages |= 1<<(stage - 1);
                    if (ch >= '0' && ch <= '9') {
                        // integer part digit found
                        pos++;
                    } else if (ch == '.'){
                        // float point found
                        pos++;
                        stage = 3;
                    } else if (ch == 'e' || ch == 'E') {
                        // E found
                        pos++;
                        stage = 5;
                    } else {
                        // the other chars are invalid
                        return false;
                    }
                    break;
                case 3: // float point collected
                    stages |= 1<<(stage - 1);
                    if (ch >= '0' && ch <= '9') {
                        // fraction part digit found
                        stage = 4;
                    } else if (ch == 'E' || ch == 'e') {
                        // E/e found
                        pos++;
                        stage = 5;
                    } else {
                        // the other chars are invalid
                        return false;
                    }
                    break;
                case 4: // fraction part digit collected
                    stages |= 1<<(stage - 1);
                    if (ch >= '0' && ch <= '9') {
                        // fraction part digit found
                        pos++;
                    } else if (ch == 'e' || ch == 'E') {
                        // e/E found;
                        pos++;
                        stage = 5;
                    } else {
                        return false;
                    }
                    break;
                case 5: // e/E collected
                    stages |= 1<<(stage - 1);
                    if (ch >= '0' && ch <= '9') {
                        // E digit found
                        stage = 7;
                    } else if (ch == '-' || ch == '+') {
                        // sign of e found
                        pos++;
                        stage = 6;
                    } else {
                        return false;
                    }
                    break;
                case 6: // sign of E collected
                    stages |= 1<<(stage - 1);
                    if (ch >= '0' && ch <= '9') {
                        // E digit found
                        stage = 7;
                    } else {
                        // others are invalid
                        return false;
                    }
                    break;
                case 7: // digit of E collected
                    stages |= 1<<(stage - 1);
                    if (ch >= '0' && ch <= '9') {
                        pos++;
                    } else {
                        return false;
                    }
                    break;
                default:
                    cout<<"case should not happen"<<endl;
                    return false;
            }
        }
        
        // should not end with these stage
        if (stage == 0 || stage == 1 || stage == 5 || stage == 6) {
            return false;
        }
        // float point collected and no preceed integer found
        // (hasn't walk through integer part stage)
        if (stage == 3 && !(stages & 1<<1)) {
            return false;
        }
        
        // E collected but no base number collected
        // (hasn't walk through neither integer part digit stage or fraction part digit stage)
        if ((stages & 1<<4) && !(stages & 1<<1) && !(stages & 1<<3)) {
            return false;
        }
        return true;
    }
};

注意截止状态的判断,状态之间的关联关系

 

第二轮:

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.

Update (2015-02-10):
The signature of the C++ function had been updated. If you still see your function signature accepts a const char * argument, please click the reload button  to reset your code definition.

尼玛,总之非常佩服自己当时的毅力。。。这回看了参考题解简洁很多

class Solution {
public:
    bool isDigit(char ch) {
        return ch >= '0' && ch <= '9';
    }
    bool isNumber(string s) {
        int len = s.size();
        int pos = 0;
        bool valid = false;
        while (pos < len && s[pos] == ' ') pos++;
        if (pos < len && (s[pos] == '-' || s[pos] == '+')) pos++;
        
        while (pos < len && isDigit(s[pos])) {
            valid = true;
            pos++;
        }
        
        if (pos < len && s[pos] == '.') {
            // accept dot won't case current number invalid if integer part existed
            // eg. 2.
            pos++;
            while (pos < len && isDigit(s[pos])) {
                // if this is the first time integer appears, eg .3
                // also can be 2.3 if integer part already exist
                valid = true;
                pos++;
            }
        }
        
        // there must be a valid number exist before we build scientific form
        if (valid && pos < len && s[pos] == 'e') {
            pos++;
            // an single e may case invalid if fellow sequence is not right
            valid = false;
            if (pos<len && (s[pos] == '+' || s[pos] == '-')) pos++;
            while(pos<len && isDigit(s[pos])) {
                valid = true;
                pos++;
            }
        }
        // only white space is permited at the end
        while (valid && pos<len && s[pos] == ' ') pos++;
        return pos == len && valid;
    }
};

  

posted @ 2014-09-22 10:29  卖程序的小歪  阅读(148)  评论(0编辑  收藏  举报