难度中等427
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
数值(按顺序)可以分成以下几个部分:
- 若干空格
- 一个 小数 或者 整数
- (可选)一个
'e'或'E',后面跟着一个 整数 - 若干空格
小数(按顺序)可以分成以下几个部分:
- (可选)一个符号字符(
'+'或'-') - 下述格式之一:
- 至少一位数字,后面跟着一个点
'.' - 至少一位数字,后面跟着一个点
'.',后面再跟着至少一位数字 - 一个点
'.',后面跟着至少一位数字
- 至少一位数字,后面跟着一个点
整数(按顺序)可以分成以下几个部分:
- (可选)一个符号字符(
'+'或'-') - 至少一位数字
部分数值列举如下:
["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]
部分非数值列举如下:
["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]
示例 1:
输入:s = "0"
输出:true示例 2:
输入:s = "e"
输出:false示例 3:
输入:s = "."
输出:false示例 4:
输入:s = " .1 "
输出:true提示:
1 <= s.length <= 20s仅含英文字母(大写和小写),数字(0-9),加号'+',减号'-',空格' '或者点'.'。
解题思路:
‘.’ 出现正确情况:只出现过一次,且在e或E的前面
‘e’、‘E’ 出现正确情况:只出现过一次,且出现前有数字
‘+’、‘-’ 出现正确情况:只能在开头和e或E后一位
该函数首先跳过字符串开头的空格,接着遍历字符串中的每个字符,标记是否出现过遇到的数字、小数点或指数符号,并检查它们出现的位置是否符合要求。最后,如果字符串末尾还有空格,必须确保它后面没有其他字符。
函数返回一个布尔值,表示字符串是否表示数值。如果字符串是数值,返回 true;否则返回 false。
其它的细节参考下面代码:
class Solution {
public:
bool isNumber(string s) {
// 跳过开头的空格
int i = 0;
while(i < s.size() && s[i] == ' ')
i++;
int start = i; // 记录一下非空格开始的第一位
// 标记是否遇到数字、小数点或指数符号
bool has_num = false;
bool has_dot = false;
bool has_exp = false;
// 遍历字符串中的每个字符
for(; i < s.size(); ++i)
{
if(isdigit(s[i])) // 判定为数字,则标记numFlag
{
has_num = true;
}
else if(s[i] == '.')
{
// 判定为'.'需要没出现过'.'并且没出现过'e'
if(has_dot == true || has_exp == true)
return false;
has_dot = true;
}
else if(s[i] == 'e' || s[i] == 'E')
{
// 判定为'e',需要没出现过'e',并且出现过数字否则false
if (has_num == false || has_exp == true)
return false;
has_exp = true;
has_num = false; // 重置数字标记,因为 e 后面必须跟整数
}
else if(s[i] == '+' || s[i] == '-')
{
// 判定为'+''-'符号,只能出现在非空格的第一位或者紧接'e'后面
if(start == i) // 是首位则不处理
continue;
if(s[i - 1] != 'e' && s[i - 1] != 'E')
return false;
}
else if(s[i] == ' ')
{
while(i < s.size() && s[i] == ' ') // 跳过末尾的空格
i++;
// 如果最后一个字符是空格,必须确保它后面没有其他字符,并且含有数字
return i == s.size() && has_num;
}
else // 其他情况,都是非法的
return false;
}
return has_num;
}
};