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); } };
'+' and '-' could follow 'e' or 'E'. e.g. +1.1e-2
ReplyDeleteYou can definitely add big "E" case, and for the "+/-" case, I think I already considered that in my code. Thanks!
DeleteHi, your code is not right. Consider this case: "-.23E+10" , your program result is false, but obviously, this is a valid number
ReplyDeleteThanks 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.
DeleteI have modified the code. Please check.
Thanks!
Below line is throwing exception for input "."
ReplyDeleteif (s[s.size()-1]=='.' && !dot && !e && s[s.size()-2]>='0' && s[s.size()-1]<='9')
Please add the condition "s.size()-1 >= 0"
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.
ReplyDeleteCould this not be solved with regular expressions?
ReplyDelete