sourcecode

Tuesday, January 1, 2013

Valid Number


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.
class Solution {//pass both large and small
        //the most complete number has the pattern below, and the sections are named accordingly:
        //-123.45e-67
        //s1
        //  d1
        //    p
        //     d2
        //       e
        //        s2
        //          d3
    struct Status{
        int s1;//first sign
        int d1;//digit
        int p;//point
        int d2;//after point, before e
        int s2;//second sign
        int e;//exponential sign
        int d3;//after e
        int sum(){return d1+d2+d3+p+e+s1+s2;}
    };
    bool isDigit(const char c){
        return (c <= '9' && c >= '0');
    }
public:
    bool isNumber(const char *s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        while(*s == ' ') ++s;//heading ' ' 
        if (!*s) return false;//empty
        
        Status r;
        r.d1 = r.d2 = r.d3 = 0;
        r.p = 0;
        r.e = 0;
        r.s1 = r.s2 = 0;
        
        const int S1 = 1;//1
        const int D1 = S1*2;//2
        const int P = D1*2;//4
        const int D2 = P*2;//8
        const int E = D2*2;//16
        const int S2 = E*2;//32
        const int D3 = S2*2;//64
        //think the numbers as a bit map
        
        while(*s != ' ' && *s != '\0'){//major loop
            switch(*s){
                case '.':
                    if (r.p || r.e) return false;
                    if (!r.s1) r.s1 = S1;
                    r.p = P;
                break;
                
                case '+':
                case '-':
                    if (r.s2 || r.d3 ) return false;
                    else if(r.s1){ 
                        if (!r.e) return false;//.-4
                        else r.s2 = S2;}
                    else r.s1 = S1;
                break;
                    
                case 'e':
                    if (r.e || r.s2) return false;
                    r.s1 = S1;//mark the defaul sign
                    r.e = E;
                break;
                
                default:
                    if (!isDigit(*s)) return false;
                    if (!r.s1) r.s1 =S1;//default sign
                    if (r.e) r.d3 = D3;
                    else if(r.p) {r.d2 = D2;}
                    else r.d1 = D1;
                    if (r.d3) r.s2 = S2;
            }
            ++s;
        }

        while(*s == ' ') ++s;//tailing ' '
        if (*s) return false;//empty
        
        int sum  = r.sum();
        switch(sum){
            case D1://123
            case S1+D1://+123, -123
            case D1+P://123.
            case P+D2://.12
            case S1+D1+P://-123.
            case S1+P+D2://-.12
            case D1+P+D2://123.3
            case S1+D1+P+D2://-123.3
            
            case D1+E+S2+D3://123
            case S1+D1+E+S2+D3://+123, -123
            case D1+P+E+S2+D3://123.
            case P+D2+E+S2+D3://.12
            case S1+D1+P+E+S2+D3://-123.
            case S1+P+D2+E+S2+D3://-.12
            case D1+P+D2+E+S2+D3://123.3

            case S1+D1+P+D2+E+S2+D3://-123.3e-45

                return true;
        }
        return false;
    }
};

No comments: