COJ1182(表达式)

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;

}

 

你可能感兴趣的:(表达式)