请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
-
数值(按顺序)可以分成以下几个部分:
1、若干空格
2、一个 小数 或者 整数
3、(可选)一个 ‘e’ 或 ‘E’ ,后面跟着一个 整数
4、若干空格 -
小数(按顺序)可以分成以下几个部分:
1、(可选)一个符号字符(’+’ 或 ‘-’)
2、下述格式之一:
1)至少一位数字,后面跟着一个点 ‘.’
2)至少一位数字,后面跟着一个点 ‘.’ ,后面再跟着至少一位数字
3)一个点 ‘.’ ,后面跟着至少一位数字 -
整数(按顺序)可以分成以下几个部分:
1、(可选)一个符号字符(’+’ 或 ‘-’)
2、至少一位数字
部分数值列举如下:
["+100", “5e2”, “-123”, “3.1416”, “-1E-16”, “0123”]
部分非数值列举如下:
[“12e”, “1a3.14”, “1.2.3”, “±5”, “12e+5.4”]
题解:
bool isNumber(string s) {
auto is_z = [&](int i, int j) {
if (s[i] == '+' || s[i] == '-') ++i;
if (i > j) return false;
for (int k = i; k <= j; ++k)
if (s[k] > '9' || s[k] < '0')
return false;
return true;
};
auto is_x = [&](int i, int j) {
if (s[i] == '+' || s[i] == '-') ++i;
int p = i;
while (p < j && s[p] != '.') ++p;
if (s[p] != '.') return false;
int l = p-i, r = j-p;
for (int k = i; k < p; ++k)
if (s[k] > '9' || s[k] < '0')
return false;
for (int k = p+1; k <= j; ++k)
if (s[k] > '9' || s[k] < '0')
return false;
return (l || r);
};
int l = 0, r = s.length()-1;
while (l < s.length() && s[l] == ' ') ++l;
while (r < s.length() && s[r] == ' ') --r;
if (l > r) return false;
int e = l;
while (e <= r && (s[e] != 'e' && s[e] != 'E')) ++e;
if (e <= r) return ((is_x(l, e-1) || is_z(l, e-1)) && is_z(e+1, r));
return is_x(l, e-1) || is_z(l, e-1);
}