Problem D: 表达式
Time Limit: 1 Sec Memory Limit: 4 MBSUBMIT: 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;
}