表达式的转换
题目描述
平常我们书写的表达式称为中缀表达式,因为它将运算符放在两个操作数中间,许多情况下为了确定运算顺序,括号是不可少的,而中缀表达式就不必用括号了。
后缀标记法:书写表达式时采用运算紧跟在两个操作数之后,从而实现了无括号处理和优先级处理,使计算机的处理规则简化为:从左到右顺序完成计算,并用结果取而代之。
例如: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 }