请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
若干空格
一个 小数 或者 整数
(可选)一个 'e' 或 'E' ,后面跟着一个 整数
若干空格
小数(按顺序)可以分成以下几个部分:
(可选)一个符号字符('+' 或 '-')
下述格式之一:
至少一位数字,后面跟着一个点 '.'
至少一位数字,后面跟着一个点 '.' ,后面再跟着至少一位数字
一个点 '.' ,后面跟着至少一位数字
整数(按顺序)可以分成以下几个部分:
(可选)一个符号字符('+' 或 '-')
至少一位数字
部分数值列举如下:
["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]
部分非数值列举如下:
["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]
class Solution
{
// 暴力模拟:读取并判断最后一位是否是结尾
// ① 只有 e 前后需要有数字
// ② 小数点需要增加一个 flag 控制,因为它可能出现在任何地方
// ③ 其他情况用 if 和 while 读取即可
public:
bool isNumber(string s)
{
int st = 0; // 起点下标
bool dot_flag = false; // ② 记录小数点是否出现
while (s[st] == ' ') // 读 前缀空格
st++;
if (s[st] == '+' || s[st] == '-') // 读 符号
st++;
// 整数 和 小数
if (s[st] == '.') // 读 小数点
{
dot_flag = true;
st++;
}
if (s[st] > '9' || s[st] < '0') // ① E 前面需要有数字
return false;
while (s[st] <= '9' && s[st] >= '0') // 读 数字
st++;
if (s[st] == '.') // 读 小数点
{
if (dot_flag)
return false; // ② 若已存在直接返回 false
else
{
st++;
while (s[st] <= '9' && s[st] >= '0')
st++;
}
}
// E 及其整数尾缀
if (s[st] == 'e' || s[st] == 'E')
{
st++;
if (s[st] == '+' || s[st] == '-') // 读 符号
st++;
if (s[st] > '9' || s[st] < '0') // ① E 后面需要有数字
return false;
while (s[st] <= '9' && s[st] >= '0')
st++;
}
while (s[st] == ' ') // 读 后缀空格
st++;
if (s[st] == '\0')
return true;
else
return false;
}
};