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 )
