题目
LeetCode: 65. Valid Number
验证给定的字符串是否为数字。
示例:
"0"
=> true
" 0.1 "
=> true
"abc"
=> false
"1 a"
=> false
"2e10"
=> true
思路
有限状态机
序列的情形是有限的,我觉得这个题有限状态机非常合适。
首先将真正需要处理的序列取出,也就是取出前面空格和后面空格的序列,这之间有几种情况:
- 空格,继续循环
- 碰到数字,终止循环
- 碰到小数点,终止循环
- 碰到其他字符,返回false
取出序列的时候要注意一下特殊情况,那就是只有一个.
,则返回false
然后分为四种情况考虑:
- 数字,直接跳过,检查下一个位置
- 小数点,看小数点前是否有e或者别的小数点
- e,e的情况看前面是否有数字序列,是否有别的e,然后需要判断e后的加减号
- 其他字符,返回false
代码
class Solution {
public:
bool isNumber(string s) {
//我的解法是有限状态机,将所有状态考虑进行排除
bool e = false;
bool ch = false;
bool num = false;
int front = 0;
int back = s.size() - 1;
//由于序列存在前面和后面有空格的情况,所以先去除前后空格
//去除前面空格
for (front; front < s.size(); front++)
{
if (s[front] == ' ')
continue;
else if ((s[front] <= '9' && s[front] >= '0') || (s[front] == '.'))
break;
else if (s[front] == '+' || s[front] == '-')
{
//遇到加号减号就将前下标放至+-之后
front++;
break;
}
else
return false;
}
//当front和size相同,说明序列全为空格
if (front == s.size())
return false;
//去除后面空格
for (back; back >= 0; back--)
{
if (s[back] == ' ')
continue;
else if ((s[back] <= '9' && s[back] >= '0') || (s[back] == '.'))
//考虑'.'的情况是因为存在序列'2.'也是合法序列
break;
else
return false;
}
if (front == back && s[front] == '.')
//存在一个序列只有一个点,特殊处理特殊情况
return false;
for (int i = front; i <= back; i++)
{
//四种情况:
//1.数字,直接跳过,检查下一个位置
//2.小数点,看小数点前是否有e或者别的小数点
//3.e,e的情况看前面是否有数字序列,是否有别的e
//4.其他字符
if (s[i] <= '9' && s[i] >= '0')
{
num = true;
continue;
}
else if (s[i] == '.')
{
if (ch == true || e == true)
return false;
else
ch = true;
}
else if (s[i] == 'e')
{
if (num == false || e == true)
return false;
else
e = true;
if (s[i + 1] == '+' || s[i + 1] == '-')
i++;
}
else
return false;
}
return true;
}
};