题目描述
验证给定的字符串是否可以解释为十进制数字。
例如:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
" -90e3 " => true
" 1e" => false
"e3" => false
" 6e-1" => true
" 99e2.5 " => false
"53.5e93" => true
" --6 " => false
"-+3" => false
"95a54e53" => false
说明
我们有意将问题陈述地比较模糊。在实现代码之前,你应当事先思考所有可能的情况。这里给出一份可能存在于有效十进制数字中的字符列表:
- 数字 0-9
- 指数 - “e”
- 正/负号 - “+”/”-“
- 小数点 - “.”
当然,在输入中,这些字符的上下文也很重要。
算法
(模拟) $O(n)$
这道题边界情况很多,首先要考虑清楚的是有效的数字格式是什么,这里用A[.[B]][e|EC]
或者.B[e|EC]
表示,其中A和C都是整数(可以有正负号也可以没有),B是无符号整数。
那么我们可以用两个辅助函数来检查整数和无符号整数的情况,从头到尾扫一遍字符串然后分情况判断,注意这里要传数字的引用或者用全局变量。
C++ 代码
class Solution {
public:
bool isNumber(string s) {
int i = 0;
while (i < s.size() && s[i] == ' ') i ++ ;
bool numberic = scanInteger(s, i);
if (s[i] == '.') numberic = scanUnsignedInteger(s, ++ i) || numberic;
if (s[i] == 'e' || s[i] == 'E') numberic = scanInteger(s, ++ i) && numberic;
while (i < s.size() && s[i] == ' ') i ++ ;
return numberic && i == s.size();
}
bool scanInteger(string& s, int& pos) {
if (s[pos] == '+' || s[pos] == '-') pos ++ ;
return scanUnsignedInteger(s, pos);
}
bool scanUnsignedInteger(string& s, int& pos) {
int p = pos;
while (pos < s.size() && s[pos] >= '0' && s[pos] <= '9') pos ++ ;
return pos > p;
}
};
这个思路好!
[e|EC]
表示什么?[]代表出现0次或1次,e|E代表指数符号,C是带符号整数。