LeetCode:valid Number

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,一个其中的小知识就可以解决这么复杂繁琐的一件事,而且思路是如此的清晰,代码是如此的简洁,虽然当时就觉得这个很棒,但是由于当时觉得好难好难,就没敢去碰他,太后悔了,不过还好有点记忆,虽然不知道其中各个环节是否符合最有的状态图,我记得当时要合并一些状态的,但是真的忘记了,等以后有空得从新学习下了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值