1. 题目

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.

2. 思路

标准答案没有考虑十六进制和八进制的问题。考虑的e指数问题,只能用e,用E时被当做非法的。
标准的合法数字形式是{前缀连续空格}{有效浮点数或整数}{e}{整数}
整体为空,或者是有e但是没有前后的数字时时非法的。
给一些case:

"3" TRUE
" 0.1 " TRUE
" .e2" FALSE
"abc" FALSE
"2e10" TRUE
".2E10" FALSE
"-2.1" TRUE
" +3321e123 " TRUE
" 0123" TRUE
" 039" TRUE
" -0x3a" FALSE
".2e81" TRUE
".2e8.1" FALSE
" +0X42 " FALSE
"e" FALSE
"." FALSE
".3" TRUE
"e2" FALSE
"2e" FALSE
"2." TRUE
" " FALSE
"+" FALSE
"-" FALSE
"46.e3" TRUE
"46e.3" FALSE
"6ee69" FALSE
" +3.2e57 " TRUE
"2E3" FALSE
"-.2e4 " TRUE
"-.2e-23" TRUE
clipboard.png

3. 代码

class Solution {
public:
    // {前缀空格}{浮点数}{e}{正数}{后缀空格}
    bool isNumber(string s) {
        bool valid = true;
        int i = 0;
        i = valid_space(s, i);
        if (i == s.length()) { return false; }
        int k = valid_float(s, i);
        bool has_prefix_float = (k != i);
        bool has_e = false;
        i = k;
        if (i < s.length() && (s[i] == 'e')) { i++; has_e = true; }
        bool has_suffix_int = false;
        if (has_e) {
            k = valid_int(s, i);
            has_suffix_int = (k != i);
            i = k;
        }
        i = valid_space(s, i);
        if (has_e && (!has_prefix_float || !has_suffix_int)) { return false; }
        return i == s.length();
    }
    
    int valid_space(string& s, int i) {
        while (i < s.length() && s[i] == ' ') { i++; }
        return i;
    }
    
    int valid_float(string&s, int i) {
        int start = i;
        int has_sign = false;
        if (i < s.length() && (s[i] == '+' || s[i] == '-')) { i++; has_sign = true; }
        bool has_prefix = false;
        while (i < s.length() && valid_number(s[i])) {
            has_prefix = true;
            i++;
        }
        bool has_point = false;
        if (s[i] == '.') { i++; has_point = true;}
        bool has_suffix = false;
        while (i < s.length() && valid_number(s[i])) { i++; has_suffix = true;}
        if ((has_point || has_sign)  && !has_prefix && !has_suffix) { return start; }
        return i;
    }
    
    int valid_int(string& s, int i) {
        int start = i;
        bool has_sign = false;
        if (i < s.length() && (s[i] == '+' || s[i] == '-')) { i++;  has_sign = true; }
        bool has_num = false;
        while (i < s.length() && valid_number(s[i])) { i++; has_num = true;}
        if (has_sign && !has_num) { return start; }
        return i;
    }
    
    bool valid_number(char ch) {
        return ch >= '0' && ch <= '9';
    }
};

knzeus
72 声望28 粉丝

行万里路,读万卷书