Thursday, January 2, 2014

[LeetCode] Valid Number

Link : 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.

Analysis:
Test case is quite important.
To make clear what if input is NULL, '\0', or "    "(only space).
exponential part is quite important.

I tried several times, and there is always some case that I didn't expect.
This is intentionally a vague problem. So ask for details from interviewers, if possible.




class Solution {
    public:
    bool isNumber(const char *s) {
        if(s==NULL||*s=='\0')
            return false;
        char *cursor = (char*)s, *cursor_left, *cursor_right;
        int dot(0), exp(0), left_sign(0), right_sign(0);
        int len(0), count_l(0), count_r(0), count_exp(0);

        // get length
        while(*cursor!='\0') {len++;cursor++;}
        if(len==0) return true;

        // skip left spaces
        cursor_left = (char*)s;
        while(*cursor_left!='\0'&&*cursor_left==' ') // skip space
        cursor_left++;
        // skip right spaces
        cursor_right = (char*)s + len - 1;
        while( (cursor_right>=cursor_left) &&(*cursor_right)==' ')
        cursor_right--;
        if(*cursor_left=='\0' || (cursor_left>cursor_right)) return false;

        // scan
        cursor = cursor_left;
        while(cursor<=cursor_right)
        {
            if(*cursor=='+'||*cursor=='-') // sign
            {
                if(exp==0)
                {   // cannot follow other sign, numbers or dot
                    if(left_sign>1||count_l>0||count_r>0||dot>0)
                        return false;
                    left_sign++;
                }
                else if(exp==1)
                {   // cannot follow other sign, numbers or dot
                    if(right_sign>1||count_exp>0)
                    return false;
                    // can only follow 'e' or 'E'
                    if(*(cursor-1)!='e'&&*(cursor-1)!='E')
                    return false;
                    right_sign++;
                }
            }
            else if(*cursor=='.')
            {   // cannot follow dot or exponential part
                if(dot>0||exp>0)//||*(cursor+1)<'0'||*(cursor+1)>'9')
                    return false;
                dot++;
            }
            else if(*cursor>='0'&&*cursor<='9')
            {
                if(exp==0)
                {
                    if(dot==0) count_l++;
                    else if(dot==1) count_r++;
                }
                else
                count_exp++;
            }
            else if(*cursor=='e'||*cursor=='E')
            {
                if(count_exp>0||exp>0) return false; // cannot follow other exponential part
                if(count_l+count_r==0) return false; // must has numbers before
                //if(*(cursor-1)<'0'||*(cursor-1)>'9') return false;
                exp++;
            }
            else
                return false;
            cursor++;
        }
        if(count_l+count_r==0) return false; // must has at least one number before exponential part
        if(exp>0&&count_exp==0) return false;// must has at least one number in exponential part, if any
        return true;
    }
}; 

int main()  
 {  
   Solution s;  
   bool result;  
   result = s.isNumber("");  
   result = s.isNumber("1");  
   result = s.isNumber("1.");  
   result = s.isNumber(".1");  
   result = s.isNumber("1.1");  
   result = s.isNumber("+");  
   result = s.isNumber("-");  
   result = s.isNumber(".");  
   result = s.isNumber("e");  
   result = s.isNumber("E");  
   result = s.isNumber("+1");  
   result = s.isNumber("+1.");  
   result = s.isNumber("+.1");  
   result = s.isNumber("+1.1");  
   result = s.isNumber("+1.1e");  
   result = s.isNumber("+1.1e2");  
   result = s.isNumber("+1.1e+2");  
   result = s.isNumber("+1.1e-2");  
   result = s.isNumber("+1.1e-2e");  
   result = s.isNumber("+1.1e-2e3");  
   system("pause");  
   return 0;  
 }  

No comments:

Post a Comment