codevs 1107 等价表达式

传送门

题解:第一眼这题好像非常难得样子,简直没有思路。但是这可以用栈带入特殊值来解决。这里用到两个栈,一个是存贮数字,另一个存贮运算符,按优先级进行运算。当读入的运算符比运算符栈的栈顶元素优先级低时,弹出栈顶元素,然后继续判断,直到小于栈顶元素,然后将这个运算符压入栈中。若读到右括号时,则将括号里的所有运算符依次弹出进行运算,直到读到左括号。然后最后只需判断两个表达式的结果是否相同,注意多带入几个特殊值,防止出现偶然性结果。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
string str1,str2;
int n,k,m=0;
long long num[50],ys[50];//num[]数字栈,ys[]运算符栈 
long long power(long long a,long long b)//由于cmath里的power(x,y)x、y为实型,所以自定义一个,计算a的b次方 
{
    long long ans=1;
    for (int i=1;i<=b;i++)
      ans=ans*a;
    return ans;
}
void js(int p,int q)
{
    if (q==1) num[p-1]=num[p-1]+num[p];
    if (q==2) num[p-1]=num[p-1]-num[p];
    if (q==3) num[p-1]=num[p-1]*num[p];
    if (q==4) num[p-1]=power(num[p-1],num[p]);    
}
long long xx(string str)
{
   int sn,len=str.length(),p=-1,q=-1;
   long long nn=0;
   for (int i=0;i<len;i++)
    {
        if (str[i]=='a') num[++p]=k;//将a带入特殊值 
        else if (str[i]>='0'&&str[i]<='9')
          nn=nn*10+(str[i]-'0');
        else if (str[i]!=' ')
          {
              if (nn!=0) 
              {
                  num[++p]=nn;
                  nn=0;
              }
             if (str[i]=='+') sn=1;//枚举运算符,并各用一数字表示 
             if (str[i]=='-') sn=2;
             if (str[i]=='*') sn=3;
             if (str[i]=='^') sn=4;
             if (str[i]=='(') sn=5;
             if (str[i]==')') sn=6;
             if (sn==5) ys[++q]=sn;//读入到左括号 
             else if (sn==6)//读入右括号,将括号内先进行运算。 
               while (q>=0&&ys[q--]!=5) js(p--,ys[q+1]);
             else 
               {
                     while (q>=0&&ys[q]<=4&&ys[q]>=sn) js(p--,ys[q--]);
                     ys[++q]=sn;
               }           
          }
    }
    if (nn!=0)//清空栈 
      {
           num[++p]=nn;
           nn=0;
      }
    while (q>=0) js(p--,ys[q--]);
    return num[0];
}
int main()
{
    getline(cin,str1);
    cin>>n;
    getline(cin,str2); //避免换行符的影响,这个读入的是空字符串 
    while (n--)
      {
           bool f=true;
           getline(cin,str2);
           for (int i=17;i<=27;i++)//枚举几个例子,将其带入a,计算两个表达式结果是否相同 
             {
                   k=i;
                   if (xx(str1)!=xx(str2)) //判断两个表达式结果是否相同 
                {
                   f=false;
                   break;
                }
             }
             
          if (f) cout<<(char)('A'+m);
          m++;     
      }
    cout<<endl;
    return 0;
} 
参考黄学长博客

 

posted @ 2016-07-25 19:11  外婆桥  阅读(155)  评论(0编辑  收藏  举报