判断表达式是否合法(推荐:*****)

Problem D: 表达式

Time Limit: 1 Sec   Memory Limit: 4 MB
SUBMIT: 375   Solved: 31
[SUBMIT] [STATUS]

Description

设S是一个合法的表达式,E为一个数字字符序列,则合法的表达式可以表示为:E, +E, -E, (S),+(S),-(S),S+(S),S-(S),S*(S),S/(S) 等。(E可以是全‘0’的字符串)。
请注意+S, -S, S+S等不一定是合法的表达式,因为可能出现如“+-E”运算符相邻情况,另外出现“()”括号中没有元素的表达式也是不合法的。

Input

 每行一个字符串,最长不超过1023个字符。可能有空行。

Output

 如果表达式合法,输入“Yes”,否则输入“No”,然后换行。
如果表达式为空,则输出一个空行。

Sample Input

-1+2
+-1+2

+(-1+2)
()-23

Sample Output

Yes
No

Yes
No

 

/*
这道题,纠错时间主要在两个栈的存储顺序不一样!
*/
#include <cstdio>
#include <cstring>
bool isOpe(char c)
{
	if(c=='+' || c=='-' || c=='*' || c=='/')
		return true;
	return false;
}
bool isDig(char c)
{
	if(c>='0' && c<='9')
		return true;
	return false;
}
bool check(char stack[],int top)
{
	bool ok=true;
	for(int i=0;i<=top;i++)
	{
		if(isOpe(stack[i]) && (i==top || (i<top && isOpe(stack[i+1]))))
			ok=false;
		else if(isDig(stack[i]) && i<top && stack[i+1]=='#')
			ok=false;
		else if(stack[i]=='#' && i<top && isOpe(stack[i+1]))
			ok=false;
	}
	return ok;
}
int main()
{
	freopen("data.in","r",stdin);
	const int nMax=1024+10;
	char stack1[nMax],stack2[nMax];
	char line[nMax];
	int top1,top2;
	while(gets(line))
	{
		
		bool ok=true;
		top1=-1;
		top2=-1;
		int len=strlen(line);
		if(len==0)
		{
			printf("\n");
			continue;
		}
		for(int i=0;i<len;i++)
		{
			if(line[i]!=')')
				stack1[++top1]=line[i];
			else
			{
				while(top1!=-1 && stack1[top1]!='(')
					stack2[++top2]=stack1[top1--];
				for(int j=0;j<=top2/2;j++)
				{
					char temp=stack2[top2-j];
					stack2[top2-j]=stack2[j];
					stack2[j]=temp;
				}
				if(top2==-1) ok=false;
				else if(top1==-1) ok=false;
				else if(!check(stack2,top2)) ok=false;
				else if(stack1[top1--]!='(') ok=false;
				else top2=-1,stack1[++top1]='#';
			}
		}
		if(!check(stack1,top1)) ok=false;
		if(ok) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}
/*
解法借鉴与:CSGrandeur 
主要思想:
①去空格
②括号匹配,递归判断处理
③确定性有限自动生成器---*****
*/

#include <cstdio>
#include <cstring>
const int nMax=1024+10;
char line[nMax];
int f[4][1<<7];
#define ORI 0
#define NUM 1
#define OPR 2
#define YKH 3
#define FAIL -1
void Delete_Blank(int len)
{
	int i,j;
	for(i=0,j=0;i<len;i++)
	{
		if(line[i]!=' ' && line[i]!='\t')
			line[j++]=line[i];
	}
	line[j]=0;
}
void Init()
{
	memset(f,-1,sizeof(f));
	f[ORI]['+']=f[ORI]['-']=OPR;
	f[NUM]['+']=f[NUM]['-']=f[NUM]['*']=f[NUM]['/']=OPR;
	for(int i='0';i<='9';i++)
		f[ORI][i]=f[NUM][i]=f[OPR][i]=NUM;
	f[ORI]['(']=f[OPR]['(']=YKH;
}
int Find_Next_Pos(int x,int y)
{
	int num=1;
	for(int i=x;i<y;i++)
	{
		if(line[i]=='(')
			num++;
		else if(line[i]==')')
			num--;
		if(num==0)
			return i;
	}
	return -1;
}
bool IsExpression(int x,int y)
{
	int state=ORI;
	for(int i=x;i<y;i++)
	{
		state=f[state][line[i]];
		if(state==YKH)
		{
			int next=Find_Next_Pos(i+1,y);
			if(next!=-1 && IsExpression(i+1,next))
				state=NUM,i=next;
			else return false;
		}
		else if(state==FAIL)
			return false;
	}
	return state==NUM;
}
int main()
{
	freopen("data.in","r",stdin);
	while(gets(line))
	{
		
		if(!line[0])
		{
			printf("\n");
			continue;
		}
		int len=strlen(line);
		Delete_Blank(len);
		len=strlen(line);
		Init();
		if(IsExpression(0,len))
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}


你可能感兴趣的:(判断表达式是否合法(推荐:*****))