表达式的转换

题目描述

平常我们书写的表达式称为中缀表达式,因为它将运算符放在两个操作数中间,许多情况下为了确定运算顺序,括号是不可少的,而中缀表达式就不必用括号了。
后缀标记法:书写表达式时采用运算紧跟在两个操作数之后,从而实现了无括号处理和优先级处理,使计算机的处理规则简化为:从左到右顺序完成计算,并用结果取而代之。
例如:8–(3+2*6)/5+4可以写为:8 3 2 6*+5/–4+
其计算步骤为:8 3 2 6 * + 5 / – 4 + 
8 3 12 + 5 / – 4 + 
8 15 5 / – 4 + 
8 3 – 4 + 
5 4 + 
9
编写一个程序,完成这个转换,要求输出的每一个数据间都留一个空格。

输入格式

就一行,是一个后缀表达式。输入的符号中只有这些基本符号“0123456789+-*/^()”,并且不会出现形如2*-3的格式。
表达式中的基本数字也都是一位的,不会出现形如12形式的数字。
所输入的字符串不要判错。

输出格式

若干个中缀表达式,第I+1行比第I行少一个运算符和一个操作数,最后一行只有一个数字,表示运算结果。
运算的结果可能为负数,“/”以整除运算。并且中间每一步都不会超过2^31。

 

 

 

一直以来做中缀表达式转后缀表达式都是我的一个目标,今天终于实现了。

但这道题难的部分并不是转的过程,而是将后缀表达式分步计算的过程。

废了我一上午。

我想了一个办法。

将中缀转后缀之后,按照顺序将后缀表达式中的符号标记顺序。

这样,每步计算的时候从所有运算符中取顺序最小的那个(顺序最少说明当前轮到它的计算),然后在运算数种选取最靠近该运算符且比运算符顺序小的两个数,运算。

另外答案的输出也是一个难办的事。

 1 #include<iostream>
 2 #define fin cin
 3 #define fout cout
 4 using namespace std;
 5 
 6 string ans,s;
 7 char fu[100];int f=0;
 8 struct{int big,site;}z[100];int totz=0;
 9 struct{char a;int site;}c[100];int totc=0;
10 
11 int Getbig(char a){
12     if(a=='#') return -1;
13     if(a=='(') return 0; 
14     if(a=='+'||a=='-') return 1;
15     if(a=='*'||a=='/') return 2;
16     if(a=='^') return 3;
17     } 
18 
19 int Count(int a,int b,char c){
20     if(c=='+') return a+b;
21     if(c=='-') return a-b;
22     if(c=='*') return a*b;
23     if(c=='/') return a/b;
24     if(c=='^')
25     {
26       int t=1;
27       while(b>0)
28       t*=a,b--;
29       return t;
30               }
31     
32     }
33 
34 int main()
35 {
36     int i,j,k;
37     fin>>s;fu[0]='#';
38     
39     for(i=0;i<s.size();++i)
40     { 
41       if(s[i]<='9'&&s[i]>='0') ans+=s[i],ans+=" ";
42       else if(s[i]=='(') fu[++f]='(';
43       else if(s[i]==')') {while(fu[f]!='(') {ans+=fu[f],ans+=" ";f--;}f--;}
44       else if(Getbig(s[i])>Getbig(fu[f])) fu[++f]=s[i];
45       else if(Getbig(s[i])<=Getbig(fu[f]))
46       {
47         while(Getbig(s[i])<=Getbig(fu[f])) 
48         {ans+=fu[f],ans+=" ";f--;} 
49         fu[++f]=s[i];                                        
50                                      }
51             }
52             
53     while(f>0)
54     ans+=fu[f--],ans+=" ";
55     for(i=0;i<ans.size()-1;++i)
56     fout<<ans[i];fout<<endl;
57     
58     int tot=0;
59     for(i=0;i<ans.size();++i)
60     if(ans[i]==' ') continue;
61     else if(ans[i]<='9'&&ans[i]>='0') {z[++totz].big=ans[i]-'0';z[totz].site=tot++;}
62     else {c[++totc].a=ans[i];c[totc].site=tot++;}
63 
64     while(1)
65     {
66       if(totc<=0) break;
67       char a=c[1].a;int site=c[1].site;
68       for(i=2;i<=totc;++i)
69       c[i-1].a=c[i].a,c[i-1].site=c[i].site;
70       totc--;
71       
72       int ma=0;
73       for(i=1;i<=totz;++i) 
74       if(z[i].site<site&&z[i].site>ma) {ma=z[i].site;j=i;}
75       
76       int d=Count(z[j-1].big,z[j].big,a);
77       
78       z[j-1].big=d;
79       
80       for(j;j<totz;++j)
81       z[j].big=z[j+1].big,z[j].site=z[j+1].site;
82       totz--;
83       
84       bool p=0;
85       for(i=1;i<=totz;++i)
86       {
87         if(p==0) {fout<<z[i].big;p=1;}
88         else fout<<" "<<z[i].big;
89         for(j=1;j<=totc;++j)
90         if(c[j].site>z[i].site&&(c[j].site<z[i+1].site||i==totz)) {if(p==0) fout<<c[j].a,p=1;else fout<<" "<<c[j].a;}
91                           }
92       fout<<endl;
93             }
94     return 0;
95     }

转载于:https://www.cnblogs.com/noip/archive/2012/08/30/2663345.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值