中缀转后缀表达式
试题描述
为了便于处理表达式,常常将普通表达式(称为中缀表示)转换为后缀{运算符在后,如X/Y写为XY/表达式。在这样的表示中可以不用括号即可确定求值的顺序,如:(P+Q)*(R-S) → PQ+RS-*。后缀表达式的处理过程如下:扫描后缀表达式,凡遇操作数则将之压进堆栈,遇运算符则从堆栈中弹出两个操作数进行该运算,将运算结果压栈,然后继续扫描,直到后缀表达式被扫描完毕为止,此时栈底元素即为该后缀表达式的值。
输入一个中缀表达式,编程输出其后缀表达式,要求输出的后缀表达式的运算次序与输入的中缀表达式的运算次序相一致。为简单起见,假设输入的中缀表达式由+(加)、-(减)、×(乘)、/(除)四个运算符号以及左右圆括号和英文字母组成,其中算术运算符遵守先乘除后加减的运算规则。假设输入的中缀表达式长度不超过200个字符,且都是正确的,即没有语法错误,并且凡出现括号其内部一定有表达式,即内部至少有一个运算符号。
输入格式
只有一行,为中缀表达式
输出格式
只有一行,为转换后的后缀表达式
输入示例
X+A*(Y-B)-Z/F
输出示例
XAYB-*+ZF/-
【分析】
直接模拟栈,具体步骤如下:
1、从左到右扫描每一个字符。如果扫描到的字符是操作数(如a、b等),就直接输出这些操作数。
2、如果是左括号,直接入栈;
3、如果是右括号,则将栈中的操作符出栈(pop)并输出,直到遇见左括号“(”。将栈中的左括号出栈(pop )。继续扫描下一个字符;
4、如果栈空,直接入栈;
5、如果当前操作符的优先级低于栈顶的操作符,就将堆出口的操作符出栈(pop)并输出, 直到该操作符的优先级大于栈顶的操作符。将当前的操作符入栈(push)。 6、如果最后栈非空,将栈中的所有操作符出栈。
1 #include<bits/stdc++.h> 2 using namespace std; 3 string s; 4 stack<char> st; 5 map<char,int> mp; //优先级 6 int main(){ 7 mp['+']=mp['-']=1; 8 mp['*']=mp['/']=2; 9 mp['(']=mp[')']=3; 10 cin>>s; 11 s='('+s+')'; 12 for(int i=0;i<s.size();i++){ 13 if(s[i]>='a'&&s[i]<='z'||(s[i]>='A'&&s[i]<='Z')) cout<<s[i]; 14 else{ //如果非操作数 15 if(s[i]=='(') { 16 st.push(s[i]);continue; 17 } 18 if(s[i]==')'){ 19 while(st.top()!='('){ 20 cout<<st.top();st.pop(); 21 } 22 st.pop();// 左括号出栈 23 continue; 24 } 25 if(st.empty() || mp[s[i]]>mp[st.top()]){ 26 st.push(s[i]); 27 continue; 28 } 29 if(st.top()=='(') st.push(s[i]); 30 else{ 31 while(st.size()&&st.top()!='('&&mp[s[i]]<=mp[st.top()]){ 32 cout<<st.top(); 33 st.pop(); 34 } 35 st.push(s[i]); 36 } 37 } 38 } 39 } 40 while(st.size()){ 41 cout<<st.top(); 42 st.pop(); 43 } 44 }