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
第一次写自动机,最开始没调用初始化自动机的函数,调了n久,测试数据对后,交上去又WA,反复检查了自动机好几遍,硬是没发现错误,最后无意中发现输出的是“Yes”和“No”,而我写成了“YES"和”NO",改过之后就AC了……
View Code
#include <stdio.h> #include <string.h> #define INI 0 #define NUM 1 #define OPT 2 #define WRN -1 #define N 1024 int table[4][130]; char s[N]; int n; void init() { int state,ch; memset(table,0xff,sizeof(table)); for(ch='0';ch<='9';ch++) table[INI][ch]=table[NUM][ch]=table[OPT][ch]=NUM; table[INI]['+']=OPT; table[INI]['-']=OPT; table[NUM]['+']=OPT; table[NUM]['-']=OPT; table[NUM]['*']=OPT; table[NUM]['/']=OPT; } int dfa(int a,int b) { int i,j,state=INI; if(a>b) return WRN; for(i=a;i<=b;i++) { if(s[i]==' ' || s[i]=='\t') continue; if(s[i]=='(') { if(state==NUM) return WRN; int cnt=1; for(j=i+1;j<=b;j++) { if(s[j]=='(') cnt++; else if(s[j]==')') cnt--; if(cnt==0) break; } if(cnt || dfa(i+1,j-1)!=NUM) return WRN; state=NUM; i=j; } else state=table[state][s[i]]; if(state==WRN) return WRN; } if(state==NUM) return NUM; return WRN; } int main() { init(); while(gets(s)) { n=strlen(s); if(n==0) puts(""); else printf("%s\n",dfa(0,n-1)==NUM?"Yes":"No"); } return 0; }