问题来源
问题描述
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.
问题分析
问题意图十分明显,便是判断一个给定的字符串是不是一个数字。此题的标准解法应该是使用DFA进行解题。但是具体到实际中来还是看大家具体的使用,不用拘泥于传统。所以这里我就没有使用DFA来解题,而是直接分析。首先是排除首尾空格,这个c++的string类已经为我们提供了很好的搜索方法。接着排除头部的符号位,剩下的字符串就需要我们一步步排查。在碰到指数‘e’之前,我们可以简单的判断当前字符是否为 0-9 的数字或者为小数点。注意到,.2
和2.
是可以被判断为数字的,所以我们无需担忧小数点出现的位置。当碰到指数之后便采用另外一套判断方案:指数后面第一个位可以为符号位,其后不能带有小数点,只能为数字。综上判断即可解题。
解决代码
class Solution {
public:
bool isNumber(string s) {
auto realStart = s.find_first_not_of(' ');
auto realEnd = s.find_last_not_of(' ');
int num_count = 0, exp_count = 0, point_count = 0;
bool exp_flag = false;
if (s[realStart] == '+' || s[realStart] == '-')
realStart++;
for (auto i = realStart; i <= realEnd; i++) {
if (exp_flag) {
if (exp_count == 0 && num_count == 0 && (s[i] == '+' || s[i] == '-')) {
exp_count = 1;
}
else if (s[i] <= '9' && s[i] >= '0') {
num_count++;
} else {
return false;
}
} else {
if (s[i] == 'e') {
if (num_count == 0) return false;
exp_flag = true;
num_count = 0;
}
else if (s[i] <= '9' && s[i] >= '0') {
num_count++;
}
else if (s[i] == '.') {
point_count++;
} else {
return false;
}
}
}
if (num_count < 1 || point_count > 1) return false;
return true;
}
};