運算式資料
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;}