leetcode 65 valid number 解题报告
这道题目实际上很简单,至少我一眼看上去是这样子的,完全和它Hard的难度不相符合。然而这个踩的数量居然高达2k,这让我十分好奇。实际做起来……我认为出题人默认做题者知道两件事情:
.
的前后可以只有一个数字- 0是可以省略的
单看这两条没有什么问题,但是题目自动省略了如下的样例:
- ”-.8“ true
- “3.” true
- “.1” true
- “+0e-” false
- “46.e3” true
实际解法的话使用的是有限状态机,为了简单起见写的不是很符合标准。
- 状态0:开始状态,接受先导空格进入状态1.
- 状态1:先导空格状态。接受[0-9]进入整数状态3,接受-/+进入状态2,接受
.
进入状态12. - 状态2:接受[0-9]进入状态3,接受
.
进入状态12 - 状态12:为了处理小数点前后的省略问题引入的状态,接受[0-9]进入状态5
- 状态3:接受[0-9]进入状态3,接受
.
进入状态4,接受e
进入状态6 - 状态4:与状态12类似,接受
e
进入状态6,接受[0-9]进入状态5 - 状态5:接受[0-9]进入状态5,接受
e
进入状态6 - 状态6:接受[0-9]进入状态8,接受
+/-
进入状态7 - 状态7:接受[0-9]进入状态8
状态3、状态5、状态8自动通向目标状态,同时这三个状态如果接受到空格则转到状态10.
对于状态10,接受到空格则转到状态10,不然转到状态11.
其他不符合的输入都会转到状态11,状态11是死状态。
实现这个有限状态机即可,代码如下:
#include <string>
#include <iostream>
using namespace std;
class Solution {
public:
bool isNumber(string s) {
unsigned int i = 0;
int state = 0;
while(i<s.length())
{
//cout<<state<<endl;
switch(state)
{
case 0:{
if(s[i]==' ')
{
i++;
}
else
{
state = 1;
}
break;
}
case 1:{
if(judgeNumber(s[i]))
{
state = 3;
}
else if(s[i]=='+' || s[i]=='-')
{
i++;
state = 2;
}
else if(s[i]=='.')
{
i++;
state = 12;
}
else
{
state = 11;
}
break;
}
case 2:{
if(judgeNumber(s[i]))
{
state = 3;
}
else if(s[i]=='.')
{
state = 12;
i++;
}
else
{
state = 11;
}
break;
}
case 3:{
if(judgeNumber(s[i]))
{
i++;
}
else if(s[i]=='e')
{
i++;
state = 6;
}
else if(s[i]=='.')
{
i++;
state = 4;
}
else if(s[i]==' ')
{
state = 10;
}
else
{
state = 11;
}
break;
}
case 4:{
if(judgeNumber(s[i]))
{
state = 5;
}
else if(s[i]=='e')
{
i++;
state = 6;
}
else if(s[i]==' ')
{
state = 10;
}
else
{
state = 11;
}
break;
}
case 5:{
if(judgeNumber(s[i]))
{
i++;
}
else if(s[i]=='e')
{
i++;
state = 6;
}
else if(s[i]==' ')
{
state = 10;
}
else
{
state = 11;
}
break;
}
case 6:{
if(judgeNumber(s[i]))
{
state = 8;
}
else if(s[i]=='-'||s[i]=='+')
{
i++;
state = 7;
}
else
{
state = 11;
}
break;
}
case 7:{
if(judgeNumber(s[i]))
{
state = 8;
}
else{
state = 11;
}
break;
}
case 8:{
if(judgeNumber(s[i]))
{
i++;
}
else if(s[i]==' ')
{
state = 10;
}
else
{
state = 11;
}
break;
}
case 10:{
if(s[i]==' ')
{
i++;
}
else
{
state = 11;
}
break;
}
case 12:{
if(judgeNumber(s[i]))
{
state = 5;
}
else
{
state = 11;
}
break;
}
}
if(state == 11)//dead state
{
break;
}
}
if(state == 3||state==4||state == 5 ||state == 8 || state == 9 || state == 10)
{
return true;
}
else
return false;
}
bool judgeNumber(char c)
{
return c-'0'>=0&&c-'0'<=9;
}
};
int main(void)
{
Solution s;
string str = "4e+";
cout<<s.isNumber(str)<<endl;
return 0;
}