题目描述:
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
例如,字符串"+100"
,"5e2"
,"-123"
,"3.1416"
和"-1E-16"
都表示数值。
但是"12e"
,"1a3.14"
,"1.2.3"
,"+-5"
和"12e+4.3"
都不是。
注意:
- 小数可以没有整数部分,例如.123等于0.123;
- 小数点后面可以没有数字,例如233.等于233.0;
- 小数点前面和后面可以有数字,例如233.666;
- 当e或E前面没有数字时,整个字符串不能表示数字,例如.e1、e1;
- 当e或E后面没有整数时,整个字符串不能表示数字,例如12e、12e+5.4;
样例:
输入: "0"
输出: true
分析:
本题是字符串的小模拟题,考察理解能力和细心度。
根据题目要求:字符串中只能出现数字,加减号,小数点以及大小写e。
对于加减号而言:
前面不能是数字,比如1+1;
如果没有e,则字符串中至多出现一次加减号;
加减号只能出现在字符串首位或者e的后一位;
几种特殊的情况:如-.123是合法的,单独的+,-是不合法的。
对于小数点而言:至多出现一次,而且小数点前后至少有一边是数字;e的右边不能出现小数点。
对于e而言:至多出现一次;左边一位可以是.或者数字;右边一位可以是数字,如果是正负号的话,那么右边第二位一定要是数。
我们采用标志变量的办法来解决各个符合出现的次数,如果出现正负号,ab置为true,出现.,po置为true,出现e,he置为true。一旦某符号出现了一次,再出现就要返回false。当然,出现e的时候,需要将ab置为false,po置为true。
class Solution {
public:
bool isNumber(string s) {
int n = s.size();
if(!n) return false;
bool ab = false,he = false,po = false;
int p = 0;
while(p < n){
if(s[p] == '+' || s[p] == '-'){
if(ab || (p > 0 && (s[p-1] != 'e') && (s[p-1] != 'E')) || n == 1) return false;
ab = true;
}
else if(s[p] == '.'){
if(p == 0 && (p + 1 == n || !isdigit(s[p+1]))) return false;
if(he || po || (!isdigit(s[p-1]) && !isdigit(s[p+1]))) return false;
po = true;
}
else if(s[p] == 'e' || s[p] == 'E'){
if(p-1 < 0 || p+1 >= n || he) return false;
if(s[p-1] == '.' || isdigit(s[p-1])){
if(isdigit(s[p+1])) he = true;
else if((s[p+1] == '+' || s[p+1] == '-') && p+2 < n && isdigit(s[p+2])) he = true;
}
if(!he) return false;
ab = false;
po = true;
}
else{
if(!isdigit(s[p])) return false;
}
p++;
}
return true;
}
};