HNU 11704 Baidu Post Bar

来源:互联网 发布:js键值对集合 编辑:程序博客网 时间:2024/04/30 02:39

http://acm.hnu.cn/online/?action=problem&type=show&id=11704&courseid=0

题意:给你一堆语法规则,再给你一个表达式,问你这个表达式是否合法。

思路:DFA,构造一个有限状态自动机,然后进行状态转移。

代码:

#include<stdio.h>#include<string.h>#include<ctype.h>const int MAXN = 10010 ;int N, M ;struct Node{int f ;struct Node *next[26] ;}p1[500010] ,*root1 ,p2[500010] ,*root2 ;int cnt1,cnt2; char pp[211000] ;char name[20] ;void Build1(char *ch){int i, j ,idx; i = 0 ;Node *loc = root1 ,*q ;for( ; ch[i] != 0; i++){idx = ch[i] - 'a' ;if(loc->next[idx] == NULL){q = &p1[cnt1] ;q->f = 0; memset(q->next , 0 ,sizeof(q->next));loc->next[idx] = q ;cnt1 ++ ;} loc = loc->next[idx] ;}loc->f = 1 ;}void Build2(char *ch){int i, j ,idx; i = 0 ;Node *loc = root2 ,*q ;for( ; ch[i] ; i++){idx = ch[i] - 'a' ;if(loc->next[idx] == NULL){q = &p2[cnt2] ;q->f = 0; memset(q->next , 0 ,sizeof(q->next));loc->next[idx] = q ;cnt2 ++ ;}loc = loc->next[idx] ;}loc->f = 1 ;}int f[10][10] ;void Init(){memset(f , -1 ,sizeof(f));f[1][1] = 2 ;f[2][2] = f[8][2] = 3 ;f[3][4] = 8 ;f[3][3] = 4 ;f[4][2] = f[6][2] = 5 ;f[5][4] = 6 ;f[5][6] = 7 ;f[5][5] = 2 ;}bool is_noun(char *ch){Node *loc = root1 ;int idx ;for(int i=0;ch[i]!=0;i++){idx = ch[i] - 'a' ;if( loc->next[idx] == NULL)return false ;loc = loc->next[idx] ;}return loc->f ; }bool is_verb(char *ch){Node *loc = root2 ;int idx ;for(int i=0;ch[i]!=0;i++){idx = ch[i] - 'a' ;if( loc->next[idx] == NULL)return false ;loc = loc->next[idx] ;}return loc->f ;}bool is_and(char *ch){return strcmp(ch , "and") == 0;}bool is_one(char *ch){return strcmp(ch , ",") == 0 ;}int judge(char *ch){int i , j ;if( is_noun(ch) )return 0 ;if( is_verb(ch) )return 1 ;if( is_and(ch) )return 2 ;if( is_one(ch) )return 3 ;return -1 ;}/*prefix : 1 noun : 2 verb : 3and : 4, : 5 sufix : 6 */bool DFA(){int state = 1 ;int len = strlen(pp);int i= 0 ,j;while(i<len && (pp[i]==' '||pp[i]=='\t') ) i++ ;if( pp[i]!='[')return false ;bool blank = 0 ;for( ;i<len && pp[i]!=']';i++){if(pp[i]==' ' || pp[i]=='\t'){blank = 1 ; break ;}}if(blank)return false ;i++ ;j = len - 1 ;while(j>=i && (pp[j]==' '||pp[j]=='\t'))j-- ;if(pp[j] != ']')return false ;blank = 0 ;for( ;j>=i && pp[j]!='[';j--){if(pp[j]==' ' || pp[j]=='\t'){blank = 1 ; break ;}}if(blank)return false ;j-- ; while(j>=i && (pp[j]==' '||pp[j]=='\t'))j-- ;len = j + 1;state = f[state][1] ;while(i<len){while(i<len && (pp[i]==' '||pp[i]=='\t'))i++ ;for(j=0 ;i<len ;i++ , j++){if( pp[i]!=' ' && pp[i]!='\t' ){name[j] = pp[i] ;}elsebreak ;}name[j] = 0 ;int kind = judge(name);switch(kind){case 0 :state = f[state][2] ; break ;case 1 :state = f[state][3] ; break ;case 2 :state = f[state][4] ; break ;case 3 :state = f[state][5] ; break ;default :return false ;}if(state == -1)return false ;}return true ;}int main(){while(scanf("%d %d",&N,&M) == 2){root1 = &p1[0] ;root1->f = 0 ;  cnt1 = 1 ;memset(root1->next, 0 ,sizeof(root1->next));for(int i=0;i<N;i++){scanf("%s",name);Build1(name); }root2 = p2 ;root2->f = 0 ;  cnt2 = 1 ;memset(root2->next, 0 ,sizeof(root2->next));for(int i=0;i<M;i++){scanf("%s",name);Build2(name); }getchar() ;gets(pp);Init(); if(DFA())printf("a good title\n");else printf("a bad title\n");}return 0 ;}


原创粉丝点击