表达式题 : poj 2269 && SGU 182
表达式资料
http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm
学过编译原理的话对这种表达式怎么算还是小儿科的吧
但是,手算会算,不代表代码可以写的好。。。。
这种题没怎么写,调试了n久
SGU 182
/* 表达式计算,我用的是栈版本 状态压缩枚举每个字母是0或1,判断原来表达式的值是否为true , 为true就输出这个状态 一些有关题意重要的信息请看forum */ #include<cstdio> #include<cstring> const int N = 3010; int mp[256]; template<typename T> struct Exp { bool error; int tot,top; T num[N]; char op[N]; void init() { error=false; tot=0; top=0; op[1]='('; } bool prior(char a,char b) { if(b=='|' || b=='<' || b=='=' || b=='#') { return a!='('; } if(b=='&') return a=='!' || a=='&'; return false; } T calc(char c,T a, T b) { if(c=='&') return a && b; if(c=='|') return a || b; if(c=='<') return a == b; if(c=='=') return!a || b; if(c=='#') return a ^ b; } T solve(char *s,int state) { int len = strlen(s); s[len++]=')'; for(int i=0; i<len; i++) { if(s[i]=='(') op[++top]=s[i]; else if(s[i]==')') { while(top>0&&op[top]!='(') { if(op[top]=='!') { num[tot]=!num[tot]; top--; } else { num[tot-1] = calc(op[top],num[tot-1],num[tot]); tot--; top--; } } top--; } else if(s[i] >= 'a' && s[i] <= 'j') { int x = mp[s[i]]; num[++tot] =( ((1<<x)&state) > 0 ); } else { while(top>0&&prior(op[top],s[i])) { if(op[top]=='!') { num[tot]=!num[tot]; top--; } else { num[tot-1] = calc(op[top],num[tot-1],num[tot]); tot--; top--; } } op[++top]=s[i]; } if(s[i]=='|' || s[i]=='=') i++; else if(s[i]=='<') i+=2; } return num[1]; } }; Exp<bool> E; char s[N]; int main() { while(gets(s)) { memset(mp,-1,sizeof(mp)); int m = 0 , len = strlen(s); char rec[15]; for(int i = 0; i < len; i++) { if(s[i] >= 'a' && s[i] <= 'j' && mp[s[i]] < 0) { rec[m] = s[i]; mp[s[i]] = m++; } } bool has = false; for(int i = 0; i < (1<<m); i++) { E.init(); if(E.solve(s,i)) { if(has) printf("||"); else has = true; for(int j = 0; j < m; j++) { if(j) printf("&"); if(!(i&(1<<j))) printf("!"); printf("%c",rec[j]); } } } if(!has) printf("a&!a"); printf("\n"); } return 0; }
poj 2269
#include<cstdio> #include<cstring> #include<string> #include<set> #include<iostream> using namespace std; const int N = 500; template<typename T> struct Exp { bool error; int tot,top; T num[N]; char op[N]; void init() { error=false; tot=0; top=1; op[1]='('; } bool prior(char a,char b) { if(b=='+' || b=='-') return a != '('; return a=='*'; } T calc(char c,T a, T b) { string ans=""; set<char> st; if(c=='+') { for(int i = 0; i < a.length(); i++) st.insert(a[i]); for(int i = 0; i < b.length(); i++) st.insert(b[i]); for(set<char>::iterator it = st.begin();it!=st.end();it++) { ans += *it; } return ans; } if(c=='-') { for(int i = 0; i < a.length(); i++) st.insert(a[i]); for(int i = 0; i < b.length(); i++) if(st.find(b[i])!=st.end()) st.erase(b[i]); for(set<char>::iterator it = st.begin();it!=st.end();it++) { ans += *it; } return ans; } if(c=='*') { for(int i = 0; i < a.length(); i++) st.insert(a[i]); for(int i = 0; i < b.length(); i++) if(st.find(b[i])!=st.end()) ans+=b[i]; return ans; } } T solve(char *s) { int len = strlen(s); s[len++]=')'; for(int i=0; i<len; i++) { if(s[i]=='(') op[++top]=s[i]; else if(s[i]==')') { while(top>0&&op[top]!='(') { num[tot-1] = calc(op[top],num[tot-1],num[tot]); tot--; top--; } top--; } else if(s[i] == '{') { i++; if(s[i]== '}') { num[++tot]=""; continue; } string tmp = ""; while(i<len && s[i] >= 'A' && s[i] <= 'Z') { // printf("i=%d\n",i); tmp += s[i]; i++; } num[++tot] = tmp; // printf("tot=%d\n",tot); // cout<<"dd"<<tmp<<endl; } else { while(top>0&&prior(op[top],s[i])) { num[tot-1] = calc(op[top],num[tot-1],num[tot]); tot--; top--; } op[++top]=s[i]; } } return num[tot]; } }; Exp<string> E; char s[N]; int main() { while(gets(s)) { E.init(); cout<<"{"<<E.solve(s)<<"}"<<endl; } return 0; }