1-3 表达式转换 (25分)
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
思路如下:
堆栈应用:表达式求值
👆浙大数据结构讲解中缀表达式如何转换为后缀表达式
👇一个博主整理的还应注意的点
参考链接
二者加持,过了…
总结:
从头到尾读取中缀表达式的每个对象,对不同对象按不同情况处理
1)运算数 直接输出
2)运算符号
*左括号:压入堆栈
*右括号:将栈顶的运算符弹出并输出,直到遇到左括号(出栈但不输出)
*其他:若优先级大于栈顶运算符压栈;否则将栈顶运算符弹出并输出,再比较新的栈顶运算符直到该运算符大于栈顶运算符为止,然后将该运算符压栈。
3)对象处理完毕,若堆栈不空把残留运算符全部输出
坑:
1)数字可能是小数、负数(负号和数字是一起输出的)或带正号的数字
2)由于嵌套括号的存在,所以不能直接输出i=0时候的字符,有可能为嵌套括号
代码如下:
#include<bits/stdc++.h>
using namespace std;
stack<char> st;
map<char,int> mp;
int main(){
mp['+'] = mp['-'] = 1; //定义运算符的优先级
mp['*'] = mp['/'] = 2;
string s="";
cin >> s;
int flag = 1;
for(int i=0;i<s.length();++i){
if(isdigit(s[i]) || s[i]=='.' || ((!i||s[i-1]=='(')&&(s[i]=='+'||s[i]=='-')) ){ //处理操作数
if(!flag) cout << " ";
else flag = 0;
if(s[i]!='+') cout << s[i];
while(s[i+1]=='.'||isdigit(s[i+1])) cout << s[++i]; //小数继续往后读
}else{ //处理运算符
if(s[i]=='(') st.push(s[i]); //(:压栈
else if(s[i]==')'){ //):将栈顶的运算符弹出并输出,直到遇到左括号(出栈,不输出)
while(!st.empty()&&st.top()!='('){
cout << " " << st.top();
st.pop();
}
st.pop();
}
else if(st.empty()||mp[s[i]]>mp[st.top()]) st.push(s[i]); //s[i]的优先级比栈顶元素的大
else{
while(!st.empty()&&st.top()!='('){ //s[i]的优先级比栈顶元素的小或等
cout << " " << st.top();
st.pop();
}
st.push(s[i]);
}
}
}
while(!st.empty()){
cout << " " << st.top();
st.pop();
}
return 0;
}