Posted on

Description

Submission

class Solution {
public:
    bool isNumber(string s) {
        if(s.empty()) return false;
        if(s[0] == ' ') return isNumber(s.substr(1, s.size() - 1));
        if(s.back() == ' ') return isNumber(s.substr(0, s.size() - 1));
        int aCount = 0, bCount = 0, cCount = 0; // a(.b) e c might be valid
        bool isExponent = false;
        bool isDecimal = false;
        bool isSignFound = false;
        for(int i = 0; i < s.size(); ++i) {
            char c = s[i];
            if(!isdigit(c) && c != 'e' && c != '+' && c != '-' && c != '.')
                return false;

            if(c == '+' || c == '-') {
                if(s[0] == c && !isSignFound) {
                    isSignFound = true;
                    continue;
                }
                if(isExponent && s[i-1] == 'e') continue;
                return false;
            }

            if(c == '.') {
                if(isExponent || isDecimal) return false;
                isDecimal = true;
            }

            if(c == 'e') {
                if(isExponent) return false;
                isExponent = true;
            }

            if(isdigit(c)) {
                if(isExponent) {
                    cCount++;
                    continue;
                }

                if(isDecimal) {
                    bCount++;
                    continue;
                }

                aCount++;
            }
        }

        if(isDecimal || isExponent) {
            if(aCount == 0 && bCount == 0) return false;
        }

        if(isExponent) {
            if (cCount == 0) return false;
        }

        return true;
    }
};

It’s about trial and error…

Local Tests

#include <iostream>

using namespace std;

class Solution {
public:
    bool isNumber(string s) {
        if(s.empty()) return false;
        if(s[0] == ' ') return isNumber(s.substr(1, s.size() - 1));
        if(s.back() == ' ') return isNumber(s.substr(0, s.size() - 1));
        int aCount = 0, bCount = 0, cCount = 0; // a(.b) e c might be valid
        bool isExponent = false;
        bool isDecimal = false;
        bool isSignFound = false;
        for(int i = 0; i < s.size(); ++i) {
            char c = s[i];
            if(!isdigit(c) && c != 'e' && c != '+' && c != '-' && c != '.')
                return false;

            if(c == '+' || c == '-') {
                if(s[0] == c && !isSignFound) {
                    isSignFound = true;
                    continue;
                }
                if(isExponent && s[i-1] == 'e') continue;
                return false;
            }

            if(c == '.') {
                if(isExponent || isDecimal) return false;
                isDecimal = true;
            }

            if(c == 'e') {
                if(isExponent) return false;
                isExponent = true;
            }

            if(isdigit(c)) {
                if(isExponent) {
                    cCount++;
                    continue;
                }

                if(isDecimal) {
                    bCount++;
                    continue;
                }

                aCount++;
            }
        }

        if(isDecimal || isExponent) {
            if(aCount == 0 && bCount == 0) return false;
        }

        if(isExponent) {
            if (cCount == 0) return false;
        }

        return true;
    }
};

void assertEqual(string s, bool expected)
{
    Solution sol;
    cout << s << "," << expected << ": ";
    cout << ((sol.isNumber(s) == expected) ? "successful" : "failed") << "\n";
}

int main() {
    Solution sol;

    assertEqual("0", true);
    assertEqual(" 0.1 ", true);
    assertEqual("abc", false);
    assertEqual("1 a", false);
    assertEqual("2e10", true);
    assertEqual(" -90e3   ", true);
    assertEqual(" 1e", false);
    assertEqual("e3", false);
    assertEqual(" 6e-1", true);
    assertEqual(" 99e2.5 " , false);
    assertEqual("53.5e93", true);
    assertEqual(" --6 ", false);
    assertEqual("-+3", false);
    assertEqual("95a54e53", false);
    assertEqual(".2e81", true);
    assertEqual("e9", false);
    assertEqual(" 005047e+6", true);

    return 0;
}

Submission 210617

class Solution {
public:
    bool isNumber(string s) {
        vector<int> states(7, 0);
        states[0] = 1;
        int state = -1;
        for(auto ch: s) {
            if(ch == '+' || ch == '-') {
                if(state == -1 || state == 4) {
                    ++state;
                } else {
                    return false;
                }
            } else if(ch == '.') {
                if(state <= 1) {
                    state = 2;
                } else {
                    return false;
                }
            } else if(ch == 'e' || ch == 'E') {
                if(state < 4 && state >= 1) {
                    state = 4;
                } else {
                    return false;
                }
            } else if(isdigit(ch)) {
                if(state < 1) {
                    state = 1;
                }
                if(state == 2 || state == 4 || state == 5) {
                    ++state;
                }
                if(states[4]) state = 6;
            } else {
                return false;
            }

            if(state == -1) {
                state = 1;
            }
            
            states[state] = 1;
        }

        if(states[2] && !states[1] && !states[3]) return false;
        if(state == 4 || state == 5) return false;

        return true;
    }
};
// 0       1                     2           3            4           5         6
// +/- => optional(digits => (optional . => digits) => optional e( => +/- => digits )

Leave a Reply

Your email address will not be published. Required fields are marked *