一、题目描述
表达式有三种表示方法,分别为:
前缀表示(波兰式):运算符+操作数1+操作数2
中缀表示:操作数1+运算符+操作数2
后缀表示(逆波兰式):操作数1+操作数2+运算符
例如:a +b * (c -d ) - e/f
波兰式:-+ab-cd/ef (运算符在操作数的前面,用递归计算波兰式)
中缀式:a+bc-d-e/f
逆波兰式:abcd-*+ef/- (运算符在操作数的后面,用栈计算逆波兰式)
中缀表示就是原表达式去掉括号。
根据表达式求波兰式、逆波兰式都是教材第三章表达式求值的思想。
求波兰式,需要操作数栈(注意不是计算结果入栈,计算式入栈),运算符栈。区别在于从后往前扫描表达式,( 换成 )。栈顶运算符优先级>新读入运算符优先级出栈,教材第三章表3.1中的相同运算符优先级>(从左往右计算)改为<,例如栈顶为+,新读入的为+,则栈顶优先级<新读入的优先级。
求逆波兰式,只需要运算符栈。操作数直接输出,操作符按表3.1优先级顺序出栈,输出。
输入表达式,求其波兰式和逆波兰式。
二、输入与输出
1.输入
测试次数
每组测试数据一行,一个合法表达式
2
4+2*3-10/5
12+3*5+(2+10)*5
2.输出
对每组测试数据,输出两行
第一行,表达式的波兰表示
第二行,表达式的逆波兰表示
不同组测试数据间以空行分隔。
- + 4 * 2 3 / 10 5
4 2 3 * + 10 5 / -
+ + 12 * 3 5 * + 2 10 5
12 3 5 * + 2 10 + 5 * +
三、参考代码
#include<stack>
#include<string>
#include<iostream>
using namespace std;
bool opr(char op1, char op2) {
if (op1 == '+' || op1 == '-')
{
return op2 == '+' || op2 == '-';
}
return true;
}
bool opl(char op1, char op2) {
if (op1 == '*' || op1 == '/') {
return op2 != '*' && op2 != '/';
}
return false;
}
class polan {
private:
stack<string> nums;
stack<char> op;
public:
string po1(string str)
{
int len = str.length();
//cout << len << endl;
for (int i = len - 1; i >= 0; --i)
{
if (str[i] >= '0' && str[i] <= '9' ) {
string num = "";
num += str[i];
while (i - 1 >= 0 && str[i - 1] <= '9' && str[i - 1] >= '0' )
{
num = str[--i] + num;
}
nums.push(num);
}
else if(op.empty() || str[i]==')' || op.top() == ')' )
{
op.push(str[i]);
}
else if (str[i] == '(')
{
while (!op.empty() && op.top() != ')')
{
string ops = "";
ops += op.top();
nums.push(ops);
op.pop();
}
op.pop();
}
else if(opr(str[i],op.top()))
{
op.push(str[i]);
}
else
{
while (!op.empty() && !opr(str[i], op.top()))
{
string ops = "";
ops += op.top();
nums.push(ops);
op.pop();
}
op.push(str[i]);
}
}
while (!op.empty())
{
string ops = "";
ops += op.top();
nums.push(ops);
op.pop();
}
string putout = "";
while (!nums.empty())
{
putout += nums.top() + (nums.size() > 1 ? " " : "");
nums.pop();
}
return putout;
}
string po2(string str)
{
int len = str.length();
string putout = "";
//cout << len << endl;
for (int i = 0; i < len; ++i)
{
if (str[i] <= '9' && str[i] >= '0') {
putout += str[i];
while (str[i + 1] <= '9' && str[i + 1] >= '0' && i + 1 < len)
{
putout += str[++i];
}
putout += " ";
}
else if (op.empty() || str[i] == '(' || op.top() == '(')
{
op.push(str[i]);
}
else if (str[i] == ')')
{
while (!op.empty() && op.top() != '(')
{
putout += op.top();
putout += " ";
op.pop();
}
op.pop();
}
else if (opl(str[i], op.top()))
{
op.push(str[i]);
}
else
{
while (!op.empty() && !opl(str[i], op.top()))
{
putout += op.top();
putout += " ";
op.pop();
}
op.push(str[i]);
}
}
while (!op.empty())
{
putout += op.top();
putout += (op.size() > 1 ? " " : "");
op.pop();
}
return putout;
}
};
int main() {
int sum;
cin >> sum;
while (sum--)
{
polan p;
string str;
cin >> str;
cout << p.po1(str) << endl;
cout << p.po2(str) << endl;
cout << endl;
}
return 0;
}