题目
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"0123"都表示数值,但"12e"、"1a3.14"、"1.2.3"、"+-5"、"-1E-16"及"12e+5.4"都不是。
思路
有效数字满足模式A[.[B]][e|EC]或者.B[e|EC]表示,其中A和C都是整数(可以有正负号,也可以没有),而B是一个无符号整数
代码
时间复杂度:O(n)
空间复杂度:O(1)
class Solution {
public:
bool isNumber(string s) {
if (s.empty()) return false;
int i = 0;
while (s[i] == ' ') ++i; // 去除开头空格
bool numeric = scanInteger(s, i);
if (s[i] == '.') {
++i; // 跳过点号
// 用 || 原因:
// 1. 小数可以没哟整数部分,如.123等于0.123
// 2. 小数点后面可以没有数字,如233.等于233.0
// 3. 小数点前后都有数字
numeric = scanUnsignedInteger(s, i) || numeric;
}
if (s[i] == 'e' || s[i] == 'E') {
++i; // 跳过e|E
// 用 && 原因:e|E 前面没有数字或后面没有整数都不能表示数字,如.e1、e1、12e、12e+5.4
numeric = numeric && scanInteger(s, i);
}
while (s[i] == ' ') ++i; // 去除结尾空格
return numeric && i == s.size();
}
bool scanInteger(string &s, int &i) {
int size = s.size();
if (i < size && (s[i] == '+' || s[i] == '-')) ++i; // 跳过正负号
return scanUnsignedInteger(s, i);
}
bool scanUnsignedInteger(string &s, int &i) {
int size = s.size(), start = i;
while (i < size && s[i] >= '0' && s[i] <= '9') ++i;
return i > start;
}
};