CSU 表达式 DFA

http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1182

题意:给你一个表达式, 问该表达式是否合法

思路:DFA 。

代码:

/*
有限状态自动机 
*/
#include<stdio.h>
#include<string.h>
#define    S     0    //初始状态 
#define	   NUM   1 	  //以数字结尾的状态	 
#define 	L    2    //左括号 
#define 	R    3    //右括号 
#define 	OPE  4    //运算符 
#define 	FAIL -1
char ch[1<<10] ;
int N ;
int f[10][20] ;

void cal(){
	int i,j ,len ;
	len = strlen(ch);
	for(i=0,j=0;i<len;i++){
		if(ch[i] == ' ')	continue ;
		ch[j++] = ch[i] ;
	}
	ch[j] = 0 ;
	N = j ;
}
void Init(){
	memset( f, FAIL , sizeof(f));
	f[S]['+']=f[S]['-']=f[S]['*']=f[S]['/']=OPE;
	f[S]['('] = L ; f[S][')'] = R ;
	for(int i='0' ;i<='9';i++){
		f[S][i] = f[NUM][i] = f[L][i] = f[OPE][i] = NUM ;
	}
	f[NUM]['+']=f[NUM]['-']=f[NUM]['*']=f[NUM]['/']=OPE;
	f[NUM][')'] = L ;
	f[L]['+']=f[L]['-']=f[L]['*']=f[L]['/']=OPE;	
	f[R]['+']=f[R]['-']=f[R]['*']=f[R]['/']=OPE;
	f[OPE]['('] = L ; f[OPE][')'] = R ;
}
int find(int s, int e){
	int cnt = 1 ;
	for(int i=s+1;i<=e;i++){
		if(ch[i] == '(')	cnt++ ;
		else if(ch[i] == ')')	cnt -- ;
		if(!cnt)	return i ;
	}
	return -1 ;
}
bool DFA(int s, int e){
	int state = S; 
	for(int i=s;i<=e;i++){
		state = f[state][ ch[i] ] ; 
		if(state == FAIL)	return false ;
		if(state == L){
			int next = find(i , e) ;
			if(next == i+1)	return false ;
			if(next==-1 || DFA(i+1,next-1)==0)	return false ;
			state = NUM ;
			i = next ;
		}
	}
	return state == NUM ;
}
int main(){
	while( gets(ch) != NULL ){
		cal() ;
		if(ch[0] == 0){
			printf("\n");	continue ;
		}
		Init() ;
		if( DFA(0,N-1) )	printf("Yes\n");
		else 				printf("No\n");
	}	
	return 0 ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值