leetcode Question 118: 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.


Analysis:

There are many cases if a number is not valid. Here the solution is definitely not optimal, but still workable and can pass all the tests.

Here are some considerations:

(1)  " . " ,   "1."  true,   "1.e2" true, ".3" true.
(2) " e ",   ".e1" false,  "1e.1" false, "1e1.1" false, "2.3e" false.
(3) "+/-",  "+1.e+5" true.

Details see code below:

Code:
class Solution {
public:

    //del the front and end spaces
    string delspace(const char* s){
        int i=0;
        while (s[i]==' '){
            i++;
        }
        int j=strlen(s)-1;
        while (s[j]==' '){
            j--;
        }
        string res="";
        for (int k=i;k<=j;k++){
            res = res+s[k];
        }
        return res;
    }
    
    
    bool valid(string &s){
        int i=0;
        bool e =false; // check if 'e' exists
        bool dot=false; // check if '.' exists
        bool dig =false;
        
        while (i<s.size()-1){
            if (i==0){ // a number can start with +, -, .
                if (s[i]<'0' || s[i]>'9'){ // if is 0-9 continue
                    if (s[i]=='+' || s[i]=='-' || s[i]=='.'){
                        if (s.size()==1){return false;} // only +, - , . is not a number
                        if (s[i]=='.'){dot=true;}
                    }
                    else {return false;}
                }else{dig=true;}
                i++;continue;
            }
            if (i>0){
                switch (s[i]){
                    case 'e': // e cannot follow +,-
                        if ( e==false && s[i-1]!='+' && s[i-1]!='-' && dig && i!=s.size()-1) {
                            e = true;
                        }else{
                            return false;
                        }
                        break;
                   case 'E': // e cannot follow +,-
                        if ( e==false && s[i-1]!='+' && s[i-1]!='-' && dig && i!=s.size()-1) {
                            e = true;
                        }else{
                            return false;
                        }
                        break;
                   case '+': // + can only occur before e
                        if (s[i-1]=='e' || s[i-1]=='E'){}else{return false;}
                        break;
                   case '-': // - can only occur before e
                        if (s[i-1]=='e' || s[i-1]=='E'){}else{return false;}
                        break;
                   case '.': // . can only occur once and cannot occure after e
                        if (dot==false && e==false){dot=true;}else{return false;}
                        break;
                   default:  // only 0-9 can be valid numbers
                        if (s[i]<'0'||s[i]>'9'){return false;}
                        else{dig = true;}
                        break;
            } 
                i++;continue;
            }
        }
        
        //last dig can only be 0-9, or ., when it is . there is no . and e before
        if (s[s.size()-1]>='0' && s[s.size()-1]<='9'){return true;}
        if (s[s.size()-1]=='.' && !dot && !e && s[s.size()-2]>='0' && s[s.size()-1]<='9') {return true;}        
        return false;
    }
    bool isNumber(const char *s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        string s1 = delspace(s); //delete spaces in the front and end, don't delete the spaces in middle.
        if (s1.size()==0){return false;} // if null string, return false;
        return valid(s1);
    }
};
        
        
        
        
        
        
        

7 comments:

  1. '+' and '-' could follow 'e' or 'E'. e.g. +1.1e-2

    ReplyDelete
    Replies
    1. You can definitely add big "E" case, and for the "+/-" case, I think I already considered that in my code. Thanks!

      Delete
  2. Hi, your code is not right. Consider this case: "-.23E+10" , your program result is false, but obviously, this is a valid number

    ReplyDelete
    Replies
    1. Thanks for the reply. I have checked the code, I figured out that the problem is "E" and "e", in my code the "E" is not considered.

      I have modified the code. Please check.

      Thanks!

      Delete
  3. Below line is throwing exception for input "."
    if (s[s.size()-1]=='.' && !dot && !e && s[s.size()-2]>='0' && s[s.size()-1]<='9')
    Please add the condition "s.size()-1 >= 0"

    ReplyDelete
  4. Hi, your code is not right. Consider this case: "1.E+10" , your program result is true, but obviously, this is not a valid number.

    ReplyDelete
  5. Could this not be solved with regular expressions?

    ReplyDelete