表达式题 : 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;
}


你可能感兴趣的:(表达式题 : poj 2269 && SGU 182)