数据结构-栈中缀表达式转后缀表达式

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+

以上是关于数据结构-栈中缀表达式转后缀表达式的主要内容,如果未能解决你的问题,请参考以下文章

中缀表达式转后缀表达式(Java代码实现)

中缀表达式如何转换为前后缀表达式?

中缀表达式转后缀表达式

中缀表达式转后缀表达式 (栈)

java简易计算机(用栈实现中缀转后缀,计算后缀表达式)

Java中缀表达式转后缀表达式并计算后缀表达式的值