表达式的转换
平常我们书写的表达式称为中缀表达式,因为它将运算符放在两个操作数中间,许多情况下为了确定运算顺序,括号是不可少的,而后缀表达式就不必用括号了。后缀标记法:书写表达式时采用运算紧跟在两个操作数之后,从而实现了无括号处理和优先级处理,使计算机的处理规则简化为:从左到右顺序完成计算,并用结果取而代之。例如:8-(3+2*6)/5+4可以写为:8 3 2 6*+5/-4+ 其计算步骤为:
(1):8 3 2 6 * + 5 / -4 +
(2):8 3 12 + 5 / - 4 +
(3):8 15 5 / - 4 +
(4):8 3- 4 +
(5):5 4 +
(6):9
编写一个程序,完成这个转换,要求输出的每一个数据间都留一个空格。
输入
就一行,是一个中缀表达式。输入的符号中只有这些基本符号“0123456789+-*/^()”,并且不会出现形如2*-3的格式。表达式中的基本数字也都是一位的,不会出现形如12形式的数字。所输入的字符串不要判错。
输出
若干个中缀表达式,第I+1行比第I行少一个运算符和一个操作数,最后一行只有一个数字,表示运算结果。运算的结果可能为负数,“/”以整除运算。并且中间每一步都不会超过2^31。
样例输入
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
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<string> #include<bitset> #include<algorithm> using namespace std; typedef long long ll; typedef long double ldb; #define inf 99999999 #define pi acos(-1.0) char s[200]; char q[11111]; char str[200]; struct node{ char c; int index; }q2[11111]; struct node1{ int num,index; }; bool operator<(node1 a,node1 b){ return a.index<b.index; } set<node1>myset; set<node1>::iterator it; int suan(int a,int b,char str) { int i,j; if(str=='+')return a+b; if(str=='-')return a-b; if(str=='*')return a*b; if(str=='/')return a/b; if(str=='^'){ int num=1; for(i=1;i<=b;i++)num*=a; return num; } } int main() { int n,m,i,j,len,front,rear,tot; node1 temp; while(scanf("%s",s+1)!=EOF) { len=strlen(s+1); memset(str,0,sizeof(str)); tot=0; front=1;rear=0; for(i=1;i<=len;i++){ if(s[i]>='0' && s[i]<='9')str[tot++]=s[i]; if(s[i]=='('){ rear++;q[rear]='('; } if(s[i]==')'){ while(front<=rear){ if(q[rear]=='('){ rear--;break; } str[tot++]=q[rear]; rear--; } } if(s[i]=='+' || s[i]=='-'){ while(front<=rear){ if(q[rear]=='(')break; str[tot++]=q[rear]; rear--; } rear++; q[rear]=s[i]; } if(s[i]=='*' || s[i]=='/'){ while(front<=rear){ if(q[rear]=='(' || q[rear]=='+' || q[rear]=='-'){ break; } str[tot++]=q[rear]; rear--; } rear++; q[rear]=s[i]; } if(s[i]=='^'){ while(front<=rear){ if(q[rear]=='(' || q[rear]=='+' || q[rear]=='-' || q[rear]=='*' || q[rear]=='/'){ break; } str[tot++]=q[rear]; rear--; } rear++; q[rear]=s[i]; } } while(front<=rear){ str[tot++]=q[rear]; rear--; } str[tot]='\0'; int flag=1; for(i=0;i<tot;i++){ if(flag)printf("%c",str[i]),flag=0; else printf(" %c",str[i]); } printf("\n"); int front2,rear2; front2=1; rear2=0; myset.clear(); for(i=0;i<tot;i++){ if(str[i]>='0' && str[i]<='9'){ temp.num=str[i]-'0';temp.index=i; myset.insert(temp); } else{ rear2++;q2[rear2].c=str[i];q2[rear2].index=i; } } char c; int index,num1,num2; while(front2<=rear2){ c=q2[front2].c; index=q2[front2].index; front2++; temp.num=1;temp.index=index; it=myset.upper_bound(temp); it--;it--; num1=(*it).num; myset.erase(it++); num2=(*it).num; myset.erase(*it++); temp.num=suan(num1,num2,c); temp.index=index; myset.insert(temp); if(myset.size()==1)break; flag=1; it=myset.begin(); int p=front2; while(1) { if(it==myset.end() && p>rear2)break; if(it==myset.end()){ printf(" %c",q2[p].c); p++;continue; } if((*it).index<q2[p].index ){ if(flag){ flag=0; printf("%d",(*it).num); } else printf(" %d",(*it).num); it++; } else{ printf(" %c",q2[p].c); p++; } } printf("\n"); } it=myset.begin(); cout<<(*it).num<<endl; } return 0; }