表达式资料
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;
}