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; } };