NPIO等价表达式AC代码

本文介绍了一种通过解析和转换数学表达式来求值的方法,并实现了一个简单的程序用于匹配和验证不同数学表达式是否相等。该程序利用了栈的数据结构进行中缀表达式到后缀表达式的转换及计算。
View Code
  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 using namespace std;
  5 
  6 typedef struct
  7 {
  8     char op;
  9     long long v;
 10     bool ok;
 11 }node1;
 12 
 13 typedef struct
 14 {
 15     int cnt;
 16     node1 I[1010];
 17 }node2;
 18 
 19 node2 E[30],H[30];
 20 int w[255];
 21 int N;
 22 
 23 bool big(char o1,char o2)
 24 {
 25     if (o1=='(') return true;
 26     if (o2=='(') return true;
 27     return w[o1]>w[o2];
 28 }
 29 void postfix(int Q)
 30 {
 31     char stack1[1010];
 32     int top=0,p=0;
 33     stack1[0]='@';
 34     for (int i=1;i<=E[Q].cnt;i++)
 35     {
 36         if (E[Q].I[i].op==0)
 37         {
 38             H[Q].I[++p].v=E[Q].I[i].v;
 39             H[Q].I[p].ok=E[Q].I[i].ok;
 40         }
 41         else
 42         {
 43             if (E[Q].I[i].op==')')
 44             {
 45                 while (stack1[top]!='(')
 46                 {
 47                     H[Q].I[++p].op=stack1[top];
 48                     stack1[top--]=0;
 49                 }
 50                 stack1[top--]=0;
 51             }
 52             else if (big(E[Q].I[i].op,stack1[top]))
 53                 stack1[++top]=E[Q].I[i].op;
 54             else
 55             {
 56                 while (!big(E[Q].I[i].op,stack1[top]) && top>0)
 57                 {
 58                     H[Q].I[++p].op=stack1[top];
 59                     stack1[top--]=0;
 60                 }
 61                 stack1[++top]=E[Q].I[i].op;
 62             }
 63         }
 64     }
 65     H[Q].cnt=p;
 66 }
 67 
 68 long long power(long long a,long long b)
 69 {
 70     long long Q=1;
 71     for (int i=1;i<=b;i++) Q*=a;
 72     return Q;
 73 }
 74 long long evaluate(int Q)
 75 {
 76     int top=-1;
 77     long long stack1[1010],a,b;
 78     for (int i=1;i<=H[Q].cnt;i++)
 79     {
 80         if (H[Q].I[i].op==0)
 81         {
 82             stack1[++top]=H[Q].I[i].v;
 83         }
 84         else
 85         {
 86             b=stack1[top--]; a=stack1[top--];
 87             switch(H[Q].I[i].op)
 88             {
 89                 case '+':
 90                     stack1[++top]=a+b;
 91                     break;
 92                 case '-':
 93                     stack1[++top]=a-b;
 94                     break;
 95                 case '*':
 96                     stack1[++top]=a*b;
 97                     break;
 98                 case '/':
 99                     stack1[++top]=a/b;
100                     break;
101                 case '^':
102                     stack1[++top]=power(a,b);
103                     break;
104             }
105         }
106     }
107     return stack1[0];
108 }
109 bool is_operator(char c)
110 {
111     return (c=='+' || c=='-' || c=='*' || c=='/' || c=='^' || c=='(' ||c==')');
112 }
113 
114 void readf(int Q)
115 {
116     int i=0; char c;
117     while (!cin.eof())
118     {
119         while ((c=cin.get())==' ');
120             if (c==10 || c==13 || cin.eof()) break;
121         i++;
122         if (is_operator(c)) E[Q].I[i].op=c;
123         else if (c=='a') E[Q].I[i].ok=true;
124         else
125         {
126             cin.putback(c);
127             E[Q].I[i].op=0;
128             cin >> E[Q].I[i].v;
129         }
130     }
131     E[Q].I[ E[Q].cnt=i+1 ].op='@';
132 }
133 void replace_letter(int P)
134 {
135     int i,j;
136     for (i=0;i<=N;i++)
137         for (j=1;j<=H[i].cnt;j++)
138             if (H[i].I[j].ok) H[i].I[j].v=P;
139 }
140 
141 void solve()
142 {
143     long long A,B,C;
144     bool right[30];
145     for (int i=1;i<=N;i++) right[i]=true;
146     for (int i=1;i<=10;i++)
147     {
148         replace_letter(rand()%100);
149         A=evaluate(0);
150         for (int j=1;j<=N;j++)
151         {
152             B=evaluate(j); C=A-B;
153             if (C<0) C=-C;
154             if (C>0.1) right[j]=false;
155         }
156     }
157     for (int i=1;i<=N;i++)
158         if (right[i]) printf("%c",i-1+'A');
159     printf("\n");
160 }
161 
162 int main()
163 {
164     w['@']=0; w['^']=3;
165     w['+']=w['-']=1;
166     w['*']=w['/']=2;
167     readf(0); postfix(0);
168     cin>>N; getchar();
169     for (int i=1;i<=N;i++)
170     {
171         readf(i); postfix(i);
172     }
173     solve();
174     return 0;
175 }

 

View Code
  1   #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std;
  5 
  6 long long check=23,
  7           result_t,
  8           final;
  9 long long num[50],//數字棧
 10           op[50]; //運算符號棧
 11 
 12 long long power(long long a,long long b)
 13 {
 14     long long k=1;
 15     for(int i=0;i<b;i++)
 16         k*=a;
 17     return k;
 18 }
 19 
 20 //操作棧頂的兩個元素
 21 void cul(int p,int op)
 22 {
 23     if(op==0) num[p-1]=num[p-1]+num[p];
 24     if(op==1) num[p-1]=num[p-1]-num[p];
 25     if(op==2) num[p-1]=num[p-1]*num[p];
 26     if(op==5) num[p-1]=power( num[p-1],num[p] );
 27 }
 28 
 29 long long result(string str)
 30 {
 31     int op_nxt,//下一個即將入棧操作符
 32         len=str.length(),
 33         p=-1,q=-1;  //數字棧、符號棧的指針
 34     long long num_nxt=0;//下一個即將入棧的數字
 35     for(int i=0;i<len;i++)
 36     {
 37         if(str[i]=='a')
 38         {
 39             num[++p]=check;
 40         }
 41         else if(str[i]>='0' && str[i]<='9')
 42         {
 43             num_nxt=num_nxt*10+(str[i]-'0');
 44         }
 45         else if(str[i]!=' ')
 46         {
 47             if( num_nxt!=0) 
 48             {
 49                 num[++p]=num_nxt;
 50                 num_nxt=0;
 51             }
 52             if(str[i]=='+') op_nxt=0;
 53             if(str[i]=='-') op_nxt=1;
 54             if(str[i]=='*') op_nxt=2;
 55             if(str[i]=='^') op_nxt= 5;
 56             if(str[i]=='(') op_nxt=6;
 57             if(str[i]==')') op_nxt=7;
 58             //如果有括號,則括號的優先級最高
 59             if(op_nxt==6)
 60             {
 61                 op[++q]=op_nxt;
 62             }
 63             else if(op_nxt==7)
 64             {
 65                 while(q>=0 && op[q--]!=6)
 66                 { //從上一個與該右括號匹配的左括號開始處理括號內的表達式
 67                     cul(p--,op[q+1]);
 68                 }
 69             }
 70             
 71             else 
 72             {    //從棧頂開始,把優先級高的運算符出棧
 73                 while( q >= 0 && op[q] <= 5 && op[q]/2>=op_nxt/2)
 74                 {
 75                     cul(p--,op[q--]);
 76                 }
 77                 op[++q]=op_nxt;
 78             }
 79         }
 80     }
 81     //在最後清空堆棧
 82     if(num_nxt!=0)
 83     {
 84         num[++p]=num_nxt;
 85         num_nxt=0;
 86     }
 87     while(q>=0)
 88     {
 89         cul(p--,op[q--]);
 90     }
 91     return num[0];
 92 }
 93 
 94 int main() 
 95 {
 96     freopen("equal.in","r",stdin);
 97     freopen("equal.out","w",stdout);
 98     string str1,str2;
 99     int n;
100     final=0;
101     getline(cin,str1);
102     cin>>n;
103     getline(cin,str2);//過濾換行符
104     while(n--)
105     {
106         bool flag=true;
107         getline(cin,str2);
108         for (int i=10;i<=20;i++)
109         {
110             check=i;
111             if (result(str1)!=result(str2))
112             {
113                 flag=false;
114                 break;
115             }
116         }
117         if (flag) cout<<(char)('A'+final);
118         final++;
119     }
120     cout<<endl;
121     return 0;
122 }

 

转载于:https://www.cnblogs.com/alanlau2011/archive/2012/07/22/2603506.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值