判斷字符串是否為合法數字。合法格式包括:整數、小數、科學計數法(含 e/E),允許前導/尾隨空格、符號(+/-)、小數點。例如:"0"、" 0.1 "、"2e10" 合法;"abc"、"1 a" 非法。
規則極其繁瑣:符號只能出現在開頭或 e/E 後;小數點最多一個且不能在 e/E 後;e/E 最多一個且前後必須有數字;空格只能在首尾。LeetCode 通過率僅 10%+,主因是邊界情況極多。
定義狀態:START、SIGN、INT、DOT、DOT_DIGIT、E、E_SIGN、E_INT、END。根據輸入字符類型(空格、符號、數字、點、e/E)轉移。最終接受狀態為 INT、DOT_DIGIT、E_INT、END。
用多個布爾標記記錄上下文:numSeen、dotSeen、eSeen、lastSpace 等。逐字符判斷:
numSeen=true,若在 e 後則標記 eNumSeen。lastSpace)時。最終合法條件:numSeen && !eSeen || (eSeen && eNumSeen) 且無非法字符。
bool isNumber(const char* s) {
bool num = false, dot = false, e = false, numAfterE = true;
while (*s) {
if (isspace(*s)) { if (num || dot || e) return false; }
else if (*s == '+' || *s == '-') { if (num || dot || (e && numAfterE)) return false; }
else if (isdigit(*s)) { num = true; if (e) numAfterE = true; }
else if (*s == '.') { if (dot || e) return false; dot = true; }
else if (*s == 'e' || *s == 'E') { if (e || !num) return false; e = true; numAfterE = false; }
else return false;
++s;
}
return num && numAfterE;
}
重點覆蓋:".1"、"3."、".e1"、"e"、" +0.1"、" -90e3 "、" 1e"、" . "、" . 1 "。