LeetCode : 剑指 Offer 20 表示数值的字符串
题目描述
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100"、“5e2”、"-123"、“3.1416”、"-1E-16"、“0123"都表示数值,但"12e”、“1a3.14”、“1.2.3”、"±5"及"12e+5.4"都不是。
解题
每日一题发现的,题目不难,只是很多细节或者情况需要考虑清楚,在尝试之后,需要明白本题对“”正确的数值字符串“的格式要求:
”1.“ ”.1“是正确的,即小数点前后必须至少存在一位数字。
” 1 “是正确的,但是” 2 3 “不是,即前后允许有空格,但数值中间不允许。
“1.e5”是正确的,即e前后保证是有效的数值表达即可。
“+.3” "+1.e-5"是正确的,即符号要么在第一位要么在e后面,且其他位置数值有效。
此外还有一些无需测试就可以明确的:
数值表达中不可以存在超过1个的‘.’或者’e’,且’.‘不能在’e’后面。由此可以大致规划我们的算法:
1. 去除两端的空格字符,只保留需要验证的子串。
2. 设置变量记录是否出现了’.’、‘e’、数字。
3. 从前向后遍历子串,每个字符做如下判断:
a. 如果是符号,则判断当前字符是否位于首位或者e后面,如果不是,则返回false。
b. 如果是’e’或’E’,则判断当前字符之前是否有有效数字,是否已经存在’.‘或者’e’‘E’,如果没有有效数字或者已经存在’.‘或者’e’‘E’则返回false,否则记录’e’或’E’已经出现。
c. 如果是’.’,则判断当前字符之前是否已经存在’.‘或者’e’‘E’,或者前后是否有有效数字,如果没有有效数字或者已经存在’.‘或者’e’‘E’则返回false,否则记录’.'已经出现.
d. 如果是数字,则记录有效数字出现,如果不是数字,直接返回false。
class Solution {
public:
bool isNumber(string s) {
if (s.size()==0) return false;
int l=0, r = s.size()-1;
while (r>=0 && s[r]==' ') --r;
while (l<s.size() && s[l]==' ') ++l;
if (r<l) return false;
bool has_dot = false, has_e = false, has_num =false;
for (int i=l; i<=r; ++i){
if (s[i]=='+' || s[i]=='-'){
if (i==r || (i!=l && (s[i-1]!='e' && s[i-1]!='E'))) return false;
}
else if (s[i]=='e' || s[i]=='E'){
if (has_e || !has_num || i==r || i==l) return false;
has_e=true;
}
else if (s[i]=='.'){
if (has_e || has_dot || !has_num && (i==r || s[i+1]<'0' || s[i+1]>'9')) return false;
has_dot=true;
}
else if (s[i]<'0' || s[i] >'9') return false;
else{
has_num = true;
}
}
return true;
}
};
也可以有其他类似的策略,比如用bool值表示当前字符是否可以是’e’、‘E’、’.'或是‘+’‘-’的一种,如果当前字符出现了不允许的字符,则返回false,实际代码略。