问题分析
什么后缀表达式
- 我们平时使用的为中缀表达式,操作符在两个操作数之间,而所谓后缀表达式,即操作符在两个操作数之后;
- 比如中缀表达式
变成后缀表达式
。
为什么要使用后缀表达式
- 在我们的认知中,我们接触一般都是中缀表达式,例如:
、
等;
- 但在计算机中,如果是像
这样简单的计算不用太多思考,但对于像
这样甚至还要稍复杂的表达式,我们要考虑到计算符优先级的问题,将其转为
才能进行计算;
- 尤其涉及到计算符优先级的表达式时,如果直接计算中缀表达式就显得有些复杂了,这里我可以将其转换为后缀表达式进行计算,以
为例:
中缀 |
后缀 |
 |
 |
-
计算过程如下:
实现方法
- 我们可以用数据机构-栈来存储操作符,以表达式
为例 ,过程如下表:
标记 |
堆栈 |
输出 |
备注 |
 |
 |
 |
 |
 |
 |
栈为空,入栈 |
 |
 |
 |
括号开始,入栈 |
 |
 |
 |
 |
 |
 |
括号未结束,入栈 |
 |
 |
 |
) |
 |
 |
括号结束,符号出栈 |
 |
 |
 |
都为乘号,优先级相同,出栈,新乘号入栈 |
 |
 |
 |
 |
 |
 |
表达式结束,全部出栈 |
操作符优先级获取
//判断是否为运算符
bool is_operator(const char temp)
{
return temp == '+' || temp == '-' || temp == '/' || temp == '*' || temp == '(' || temp == ')';
}
//得到运算符优先级
int level_operator(char temp)
{
if (temp == '+' || temp == '-')return 2;
else if (temp == '*' || temp == '/')return 1;
else return 0;
}
中缀转后缀表达式
- 这里的函数没有返回结果,而是在函数中直接输出,代码如下:
//中缀转后缀
//中缀转后缀
void Infix_convert(string ex)
{
//得到表达式长度
int length = ex.size();
stack<char>op;
//防止栈空出错
op.push('#');
for (int i = 0; i < length; i++)
{
if (!is_operator(ex[i]))cout << ex[i];
else if (ex[i] == ')')
{
for (; op.top() != '('; op.pop())
{
cout << op.top();
}
op.pop();
}
else
{
for (; level_operator(op.top()) <= level_operator(ex[i])&&op.top()!='#'&&op.top()!='('; op.pop())
{
cout << op.top();
}
op.push(ex[i]);
}
}
//将栈中的剩余操作符输出
while (op.top() != '#')
{
cout << op.top();
op.pop();
}
cout << endl;
}
代码总览
#include<iostream>
#include<stack>
#include<string>
using namespace std;
//判断是否为运算符
bool is_operator(const char temp)
{
return temp == '+' || temp == '-' || temp == '/' || temp == '*' || temp == '(' || temp == ')';
}
//得到运算符优先级
int level_operator(char temp)
{
if (temp == '+' || temp == '-')return 2;
else if (temp == '*' || temp == '/')return 1;
else return 0;
}
//中缀转后缀
void Infix_convert(string ex)
{
//得到表达式长度
int length = ex.size();
stack<char>op;
//防止栈空出错
op.push('#');
for (int i = 0; i < length; i++)
{
if (!is_operator(ex[i]))cout << ex[i];
else if (ex[i] == ')')
{
for (; op.top() != '('; op.pop())
{
cout << op.top();
}
op.pop();
}
else
{
for (; level_operator(op.top()) <= level_operator(ex[i])&&op.top()!='#'&&op.top()!='('; op.pop())
{
cout << op.top();
}
op.push(ex[i]);
}
}
//将栈中的剩余操作符输出
while (op.top() != '#')
{
cout << op.top();
op.pop();
}
cout << endl;
}
int main()
{
string exp;
cout << "请输入表达式" << endl;
cin >> exp;
Infix_convert(exp);
return 0;
}