参照龙书《编译原理》的前三章的方式写的代码,先写出文法:
{}为可选内容, || 为或者选项。
exp = term {^ term} // 异或
term = fact {| fact} // 或
fact = var {& var} // 与
var = 变量 || ! 变量 || (exp)
根据文法规则写出各个函数,设置好全局字符串指针指向的表达式,然后a = exp() 就能得到改表达式的结果。
表达式计算的时间的复杂度为O(n)。
因为最多15个变量,枚举各个变量的值的次数不超过2^15,算法总复杂度为O(l*2^n),2s内得解。
#include<stdio.h>
#include<string.h>
#include<ctype.h>
char s1[205], s2[205] ;
char e1[205], e2[205] ;
int len1, len2 ,le1, le2 ,nVar , V;
char name[20][50] ;
char *s;
int p ;
int find(char *p){
for(int i=0;i<nVar;i++){
if(strcmp( p, name[i]) == 0) return i ;
}
return -1 ;
}
int add(char *p){
strcpy(name[nVar] , p) ;
nVar ++ ;
return nVar - 1;
}
bool isOP(char c){
if(c=='!' || c=='&' || c=='|' || c=='^' || c=='(' || c==')' ) return true ;
else return false ;
}
bool exp() ;
bool term() ;
bool fact() ;
bool var() ;
/*
根据运算符的优先级来逐步完成
*/
bool exp(){
bool a ,b;
a = term() ;
while(s[p] == '^'){
p++ ;
b = term() ;
a = a ^ b ;
}
return a ;
}
bool term(){
bool a ,b ;
a = fact() ;
while(s[p] == '|'){
p++ ;
b = fact() ;
a = a | b ;
}
return a ;
}
bool fact(){
bool a , b ;
a = var();
while(s[p] == '&'){
p++ ;
b = var() ;
a = a & b ;
}
return a ;
}
bool var(){
bool a ;
if(s[p]<nVar){
a = (V&(1<<s[p])) > 0 ;
p++ ;
return a ;
}
else if(s[p] == '!'){
p++ ;
a = var() ;
a = !a ;
return a ;
}
else if(s[p] == '('){
p++ ;
a = exp() ;
p++ ;
return a ;
}
}
int main(){
int i, j ;
char str[50] ;
while(gets(s1) && s1[0]){
gets(s2) ;
i = 0 ; le1 = 0 ; le2 = 0 ; nVar = 0 ;
while( s1[i] ){
if(isalpha( s1[i] )){
j = 0 ;
while( s1[i] && isalpha(s1[i]))
str[j++] = s1[i++] ;
str[j] = 0 ;
int id = find(str);
if(id == -1) id = add(str);
e1[le1++] = id ;
}
else if(isOP( s1[i] )){
e1[le1++] = s1[i] ;
i++ ;
}
else
i++ ;
}
e1[le1] = 0 ;
i = 0 ;
while( s2[i] ){
if(isalpha( s2[i] )){
j = 0 ;
while( s2[i] && isalpha(s2[i]))
str[j++] = s2[i++] ;
str[j] = 0 ;
int id = find(str);
if(id == -1) id = add(str);
e2[le2++] = id ;
}
else if(isOP( s2[i] )){
e2[le2++] = s2[i] ;
i++ ;
}
else
i++ ;
}
e2[le2] = 0 ;
bool ok = 1 ;
for( V=(1<<nVar)-1 ;V>=0; V--){
s = e1 ;
p = 0 ;
bool exp1 = exp();
s = e2 ;
p = 0 ;
bool exp2 = exp() ;
if(exp1 != exp2){
ok = 0 ; break ;
}
}
if(ok) printf("TRUE\n");
else printf("FALSE\n");
}
return 0 ;
}