数据结构-栈中缀表达式转后缀表达式
Posted Mount256
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构-栈中缀表达式转后缀表达式相关的知识,希望对你有一定的参考价值。
中缀表达式转后缀表达式的算法思想如下(摘自王道数据结构):
- 扫描到数字:直接加入后缀表达式;
- 扫描到“(”:入栈;
- 扫描到“)”:依次把栈中的运算符加入后缀表达式,直到出现“(”,丢弃“(”;
- 扫描到运算符:(1)如果当前运算符优先级大于栈顶运算符,当前运算符直接入栈;(2)如果当前运算符优先级小于等于栈顶运算符,需要弹出当前运算符优先级小于等于栈顶的运算符,直到栈空或遇到栈顶为左括号,最后当前运算符入栈。
#include <iostream>
#include <string>
#include <stack>
using namespace std;
// 栈外优先级 (in coming priority)
int icp (const char c)
switch (c)
case '+':
case '-':
return 0; // 低优先级运算符
case '*':
case '/':
return 1; // 高优先级运算符
default:
return -1;
// 中缀表达式转化为后缀表达式
string Mid2RPN (const string s)
stack<char> opStack; // 定义运算符栈
int length = s.length();
int op_num;
string result = ""; // 后缀表达式
for (int i = 0; i < length; i++)
cout << "当前扫描:" << s[i];
switch (s[i])
case '+':
case '-':
case '*':
case '/':
if ( opStack.empty() || (icp(s[i]) > icp(opStack.top())) ) // 如果 当前运算符优先级 大于 栈顶运算符
opStack.push(s[i]); // 当前运算符 压入栈
else // 如果 当前运算符优先级 小于等于 栈顶运算符
// 需要弹出 当前运算符优先级 小于等于 栈顶的运算符,直到 栈空 或遇到 栈顶为左括号
while ( !opStack.empty() && ( (opStack.top() != '(') || (icp(s[i]) <= icp(opStack.top())) ) )
result += opStack.top(); // 栈中优先级小或相同的运算符 出栈
opStack.pop();
opStack.push(s[i]); // 弹出 栈中优先级小或相同的运算符 后,当前运算符 入栈
break;
case '(':
opStack.push(s[i]); // 压入 左括号
break;
case ')':
while ( !opStack.empty() && opStack.top() != '(' ) // 把栈中的运算符弹出,直到遇到左括号
result += opStack.top(); // 弹出 栈中的运算符
opStack.pop();
opStack.pop(); // 弹出 左括号
break;
default:
result += s[i];
break;
// 每处理完一个元素,打印中间处理过程,方便观察
if (!opStack.empty())
cout << " 当前栈顶:" << opStack.top();
else
cout << " 当前栈顶:#";
cout << " 当前后缀表达式:" << result <<endl;
// 栈中剩余的运算符依次出栈
while (!opStack.empty())
result += opStack.top();
opStack.pop();
return result;
int main()
string s, result;
//s = "a/b+(c*d-e*f)/g";
s = "a+b-a*((c+d)/e-f)+g";
cout << "中缀表达式:" << s << endl;
result = Mid2RPN(s);
cout << "最终后缀表达式:" << result << endl;
return 0;
输出结果参考:
中缀表达式:a+b-a*((c+d)/e-f)+g
当前扫描:a 当前栈顶:# 当前后缀表达式:a
当前扫描:+ 当前栈顶:+ 当前后缀表达式:a
当前扫描:b 当前栈顶:+ 当前后缀表达式:ab
当前扫描:- 当前栈顶:- 当前后缀表达式:ab+
当前扫描:a 当前栈顶:- 当前后缀表达式:ab+a
当前扫描:* 当前栈顶:* 当前后缀表达式:ab+a
当前扫描:( 当前栈顶:( 当前后缀表达式:ab+a
当前扫描:( 当前栈顶:( 当前后缀表达式:ab+a
当前扫描:c 当前栈顶:( 当前后缀表达式:ab+ac
当前扫描:+ 当前栈顶:+ 当前后缀表达式:ab+ac
当前扫描:d 当前栈顶:+ 当前后缀表达式:ab+acd
当前扫描:) 当前栈顶:( 当前后缀表达式:ab+acd+
当前扫描:/ 当前栈顶:/ 当前后缀表达式:ab+acd+
当前扫描:e 当前栈顶:/ 当前后缀表达式:ab+acd+e
当前扫描:- 当前栈顶:- 当前后缀表达式:ab+acd+e/
当前扫描:f 当前栈顶:- 当前后缀表达式:ab+acd+e/f
当前扫描:) 当前栈顶:* 当前后缀表达式:ab+acd+e/f-
当前扫描:+ 当前栈顶:+ 当前后缀表达式:ab+acd+e/f-*-
当前扫描:g 当前栈顶:+ 当前后缀表达式:ab+acd+e/f-*-g
最终后缀表达式:ab+acd+e/f-*-g+
以上是关于数据结构-栈中缀表达式转后缀表达式的主要内容,如果未能解决你的问题,请参考以下文章