眩しさだけは、忘れなかった。|

【数据结构-栈】栈在表达式求值的应用

前缀、中缀、后缀表达式的互相转换

  • 前缀表达式:也称波兰式,指运算符处于两个操作数的前面
  • 中缀表达式:指运算符在两个操作数之间的位置
  • 后缀表达式:也称逆波兰式,指运算符处于两操作数后面

【例 1】已知中缀表达式:a+b-c*d

  • 先确定运算顺序:(a+b)-(c*d)
  • 前缀表达式:- +ab *cd
  • 后缀表达式:ab+ cd* -

【例 2】已知中缀表达式:a/b+(c*d-e*f)/g

  • 先确定运算顺序:(a/b)+(((c*d)-(e*f))/g)
  • 前缀表达式:+ /ab / -*cd *ef g
  • 后缀表达式:ab/ cd* ef*- g/ +

中缀表达式转后缀表达式的算法

  • 扫描到数字:直接加入后缀表达式;
  • 扫描到“(”:入栈;
  • 扫描到“)”:依次把栈中的运算符加入后缀表达式,直到出现“(”,丢弃“(”;
  • 扫描到运算符:(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+

本文作者:漫舞八月(Mount256)

本文链接:https://www.cnblogs.com/Mount256/p/16521721.html

版权声明:本作品采用CC 4.0 BY-SA许可协议进行许可。

posted @   漫舞八月(Mount256)  阅读(147)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开
  1. 1 Main Menu Theme Syd Matters
  2. 2 Luminous Memory (Acyanxi Remix) Acyanxi
  3. 3 夏影 麻枝准
  4. 4 潮騒の香り 水月陵
  5. 5 stand still 井口裕香 (いぐち ゆか)
  6. 6 流星雨 麻枝准
  7. 7 Summer Fantasy 傅许
  8. 8 失う 米白
  9. 9 epilogue 霜月はるか
  10. 10 夏に君を待ちながら 小原好美
  11. 11 桜のような恋でした 鹿乃 (かの)
  12. 12 風は微かに、熱を残し… 水月陵
  13. 13 夏凪ぎ 麻枝准/やなぎなぎ
  14. 14 空に光る 戸越まごめ
  15. 15 木漏れ日 riya
  16. 16 Songbirds Homecomings (ホームカミングス)
  17. 17 宝物になった日 麻枝准/やなぎなぎ
  18. 18 夏影~あの飛行機雲を超えた、その先へ~ 雪桜草 (雪樱草)
  19. 19 快晴 Orangestar (蜜柑星P),初音未来 (初音ミク)
  20. 20 永遠 霜月はるか
  21. 21 Sion 天門
  22. 22 遙かな年月-piano- 麻枝准
  23. 23 夏恋慕 kobasolo/春茶
  24. 24 夏凪ぎ-piano ver.- MANYO/麻枝准
  25. 25 Goodbye Seven Seas -piano ver.- MANYO/麻枝准
  26. 26 Light Years 麻枝准/やなぎなぎ
  27. 27 優しさの記憶 鹿乃 (かの)
夏影 - 麻枝准
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.