7-20 表达式转换 (25 分)
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+
、-
、*
、\
以及左右括号()
,表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
需要支持多位数(包含小数)的加减乘除及优先级运算
另外需考虑数字带有符号(+,-)
#include <iostream>
#include <vector>
#include <map>
#include <stack>
using namespace std;
map<char, int> priority = { {'*',3},{'/',3},{'+',2},{'-',2},{'(',1}};
vector<string> trans(string m_exp) {
vector<string> p_exp;
stack<char> stk;
string operators("+-*/()");
string str;
for (int i = 0; i < m_exp.length(); i++) {
string one;
if (((m_exp[i] == '-' || m_exp[i] == '+') && (i == 0 || string("+-/*(").find(m_exp[i - 1]) != string::npos)) || isdigit(m_exp[i])) //对于非运算符,进行数字转换
{ //把操作数加入到后缀式中
str = m_exp[i] != '+' ? string({ m_exp[i] }) : "";
while (i + 1 < m_exp.length() && operators.find(m_exp[i+1]) == string::npos) {
str += m_exp[i + 1];
i++;
}
p_exp.push_back(str);
}
else { //出现操作符
if (m_exp[i] == '(') //栈中添加左括号
stk.push({ m_exp[i] });
else if (m_exp[i] == ')') { //出现右括号时,将栈中元素一直弹出,直至弹出左括号
while (stk.top() != '(') {
p_exp.push_back({ stk.top() });
stk.pop();
}
stk.pop(); //弹出左括号
}
else { //操作符的优先级判断
while ((!stk.empty()) && (priority[m_exp[i]] <= priority[stk.top()])) { //当栈不为空时,进行优先级判断
p_exp.push_back({ stk.top() }); //若当前操作符优先级低于栈顶,弹出栈顶,放到后缀式中
stk.pop();
}
stk.push({ m_exp[i] }); //将当前操作符入栈
}
}
}
while (!stk.empty()) { //将栈中剩余操作符放到后缀式中
p_exp.push_back({ stk.top() });
stk.pop();
}
return p_exp;
}
int main() {
string m_exp;
cin >> m_exp;
auto p_exp = trans(m_exp);
for (int i = 0; i < p_exp.size(); ++i)
cout << (i ? " " : "") << p_exp[i];
return 0;
}