您的位置:首页 > 其它

LeetCode:valid Number

2014-08-25 10:30 381 查看

LeetCode:Valid Number

题目
链接:https://oj.leetcode.com/problems/valid-number/
描述:

Validate if a given string is numeric.

Some examples:

"0"
=>
true


" 0.1 "
=>
true


"abc"
=>
false


"1 a"
=>
false


"2e10"
=>
true


Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.
思路1
本来想着处理所有的可能情况就可以得到最终结果,当然这也是最最直接的方法,然后自己写了很长很复杂的代码,最终也不能完全通过,下面将失败的代码贴出,或许已经接近成功也未可知,但是我已经放弃这种方法。
//give up this way..........
bool isNumber(const char *s)
{
bool res = false;
map<char,bool> symbol = {
make_pair('.',false),
make_pair('e',false),
make_pair('E',false),
make_pair('+',false),
make_pair('-',false),
make_pair(' ',false)
};
bool hasnum = false;
bool space  = false;
const char * cur = s;
while(*cur == ' ')
{
cur++;
space = true;
}
if (*cur == '\0')
{
return false;
}
symbol[' '] = true;
while(*cur != '\0')
{
if (*cur >= '0' && *cur <= '9')
{
hasnum = true;
cur++;
continue;
}
switch(*cur)
{
case '.':
if (symbol['.'])
{
return false;
}
else
{
if (hasnum && (symbol['e'] || symbol['E']))
{
return false;
}
if ((*(cur + 1) == '\0')&&((*(cur - 1) == ' ')||*(cur - 1) == '+' || *(cur - 1) == '-' || *(cur - 1) == 'e' || *(cur - 1) == 'E' || !hasnum))
{
return false;
}
symbol['.'] = true;
}
break;
case '+':
if (symbol['+'])
{
return false;
}
else
{
if (hasnum && (!symbol['e'] || !symbol['E']))
{
return false;
}
if (!(*(cur - 1) == 'e' || *(cur - 1) == 'E') )
{
return false;
}
if(*(cur + 1) == '\0' || *(cur + 1) == 'e' || *(cur + 1) == 'E'||*(cur + 1) == '+' ||*(cur + 1) == '-')
return false;
symbol['+'] = true;
}
break;
case '-':
if (symbol['-'])
{
return false;
}
else
{
if (hasnum && (symbol['e'] || symbol['E']))
{
return false;
}
// if (!(*(cur - 1) == 'e' || *(cur - 1) == 'E') )
// {
// 	return false;
// }
if (*(cur + 1) == '\0' || *(cur + 1) == 'e' || *(cur + 1) == 'E'||*(cur + 1) == '+' ||*(cur + 1) == '-')
{
return false;
}
symbol['-'] = true;
}
break;
case 'e':
case 'E':
if (symbol['E'] || symbol['e'])
{
return false;
}
else
{
if (!hasnum)
{
return false;
}
if(*(cur + 1) == '\0' || cur == s || *(cur + 1) == 'e' || *(cur + 1) == 'E' || *(cur + 1) == ' ')
return false;
symbol['E'] = true;
symbol['e'] = true;
symbol['+'] = false;
symbol['-'] = false;
symbol['.'] = true;
}
break;
default:
// if ((*(cur-1) == '+' || *(cur-1) == '-' || *(cur-1) == 'e' || *(cur-1) == 'E') && !hasnum )
// {
// 	return false;
// }
while(*cur == ' ') cur++;
if (*cur == '\0' && hasnum)
{
return true;
}
return false;
break;
}
cur++;
}
return true;
}


思路2
有限自动机才是王道,凭借着本科好几年前的对编译原理中状态图的记忆,自己绘制了一下这个问题的状态图,或许其中有些状态是多余的,但是可以解决此问题了。主要思路是从开始,寻找输入各种数字之后状态会发生怎么的转变,每一个状态都要考虑所有输入,最终绘制的状态转换图如下:



之后根据状态图写出代码如下:
bool isNumber(const char * s)
{
enum symbol
{
START = 0, //start
PLUS,
MINUS,
E,
NUM,
DOT,
SPACE
};
int statements[][7] = {
-1,1,1,-1,3,2,0,//start
-1,-1,-1,-1,3,2,-1, //1
-1,-1,-1,-1,4,-1,-1, //2
-1,-1,-1,5,3,4,8,//3
-1,-1,-1,5,4,-1,8,//4
-1,6,6,-1,7,-1,-1,//5
-1,-1,-1,-1,7,-1,-1,//6
-1,-1,-1,-1,7,-1,8,//7
-1,-1,-1,-1,-1,-1,8
};
int flag = 0;
while(*s != '\0')
{
switch(*s)
{
case '+':
flag = statements[flag][PLUS];
break;
case '-':
flag = statements[flag][MINUS];
break;
case 'e':
case 'E':
flag = statements[flag][E];
break;
case '.':
flag = statements[flag][DOT];
break;
case ' ':
flag = statements[flag][SPACE];
break;
case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':
flag = statements[flag][NUM];
break;
default:
return false;
break;
}
cout<<*s<<"->"<<flag<<endl;
if (flag == -1)
{
return false;
}
s++;
}
if (flag == 3 || flag == 4 || flag == 7 || flag == 8)
{
return true;
}
return false;
}


最终发现,编译原理果然NB,一个其中的小知识就可以解决这么复杂繁琐的一件事,而且思路是如此的清晰,代码是如此的简洁,虽然当时就觉得这个很棒,但是由于当时觉得好难好难,就没敢去碰他,太后悔了,不过还好有点记忆,虽然不知道其中各个环节是否符合最有的状态图,我记得当时要合并一些状态的,但是真的忘记了,等以后有空得从新学习下了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: