571-中缀转后缀(逆波兰式)

在这里插入图片描述

中缀转后缀(逆波兰式)示例1

在这里插入图片描述
依然是需要1个栈结构(符号栈)(存放运算符的)
在这里插入图片描述
我们从头开始遍历。
遇见小括号(了,因为栈是空的,左括号(入栈
在这里插入图片描述
然后遇见1,中缀转后缀,碰见数字,直接输出。
在这里插入图片描述
然后遇见+号,针对于栈里的左括号(,优先级是高还是低?
只要栈顶是左括号(,就有一个优先级比较高的式子出现了,所以+比左括号(的优先级要大,也就是说,现在遇到的任意符号都比栈顶的左括号(优先级要大,所以这个+号直接入栈,在这里插入图片描述
然后遇见2,遇见数字,直接输出
在这里插入图片描述
然后遇见右括号)
有右括号,那么之前就一定有左括号了,我们就要从右括号)开始,一直运算,直到碰见左括号(为止
因为小括号括起来的优先级是最大的
一直算到把左括号(出栈
在这里插入图片描述
接着遇到 *,栈是空的,直接把 * 入栈
然后遇到左括号(,左括号(入栈
在这里插入图片描述
左括号是优先级比较高的表达式的开始。
只要遇到左括号,就不用比较优先级了,直接入栈

然后遇见3,直接输出
在这里插入图片描述
然后遇见+,这个+要和栈顶元素比较,一看这个栈顶元素是(,遇见左括号(都是直接入栈。
然后碰见4,直接输出
在这里插入图片描述
然后碰见右括号),开始计算这个小括号的内容了,然后右括号)就不用入栈了,+直接出栈,然后左括号(出栈,
如果遍历遇到右括号,就直接出栈,直到左括号(出栈。
在这里插入图片描述
相当于是把一个小括号的表达式处理完了。
最后符号栈剩下的按原样输出
在这里插入图片描述

在这里插入图片描述

中缀转后缀(逆波兰式)示例2

在这里插入图片描述
我们从头开始遍历。遇见数字2,直接输出。
在这里插入图片描述
然后遇见符号+,现在栈是空的,就直接入栈。
然后遇见左括号(,左括号直接入栈,因为左括号(是优先级更高的表达式的开。

在这里插入图片描述
然后遇见4,直接输出在这里插入图片描述
然后遇见符号+,此时栈顶元素是左括号(,任何符号和左括号比,都是认为优先级高,直接入栈就好啦,
在这里插入图片描述
然后遇见6,直接输出
在这里插入图片描述
然后遇见右括号),就不用入栈了,就是现在是优先级最高的表达式,就直接一直出栈,计算,直到到左括号(输出出来就结束,在这里插入图片描述
然后遇见除法/,此时栈顶元素是+,/的优先级高,直接入栈。
在这里插入图片描述
然后遇见数字2,直接输出
在这里插入图片描述
然后遇见符号+,此时栈顶元素是/,+的优先级比/低啊,所以先计算除法/,把除法/出栈,在这里插入图片描述
然后继续比较,现在是符号+和栈顶元素+比较,优先级一样,按顺序从左向右算,栈里的+出现的比较早,所以也是出栈,先计算。
在这里插入图片描述
现在栈空了,没得比较了,把6前面的符号+入栈,
在这里插入图片描述
然后遇见数字6,直接输出
在这里插入图片描述
然后遇见除法/,优先级高于此时的栈顶元素+,/直接入栈,
然后遇见数字3,直接输出
在这里插入图片描述
然后把栈里的符号依次输出就完了。
在这里插入图片描述
我们验证一下中缀
在这里插入图片描述
最后结果是2+5+2=9

我们验证一下后缀
在这里插入图片描述
后缀表达式在求解的时候,把数字入栈
在这里插入图片描述
然后遇见符号+
出栈2个元素进行+号运算,得出结果10,入栈
在这里插入图片描述
然后遇见数字2,就入栈
在这里插入图片描述
然后遇见除法/,
出栈2个元素,先出栈的作右操作数,后出栈的作左操作数
2和10出栈,10/2=5,5入栈
在这里插入图片描述
然后遇见+号,出栈2个元素,2和5,2+5=7,7入栈
在这里插入图片描述
然后遇见数字6,入栈,然后遇见数字3,入栈
在这里插入图片描述
然后遇见除法/,出栈3和6两个元素,6/3=2,2入栈
在这里插入图片描述
最后遇见符号+,出栈2个元素,7+2=9,最后的结果:9

中缀转后缀总结

在这里插入图片描述

代码实现

#include <iostream>
#include <string>
#include <stack>
using namespace std;

//比较符号优先级的函数 
bool Priority(char ch, char topch)
{
	if ((ch == '*' || ch == '/') && (topch == '+' || topch == '-'))
		return true;
	if (topch == '(' && ch != ')')
		return true;
	return false;
}

//中缀表达式 => 后缀表达式
string MiddleToEndExpr(string expr)
{
	string result;//定义结果 
	stack<char> s;//存储的是符号 

	for (char ch : expr)//遍历字符串 
	{
		if (ch >= '0' && ch <= '9')//如果遇见数字,直接输出 
		{
			result.push_back(ch);//输出的结果放在result里面 
		}
		else//如果遇见的是符号 
		{
			for (;;)
			{
				//处理符号了
				if (s.empty() || ch == '(')//如果当前栈是空的,或者当前符号是(,直接入栈 
				{
					s.push(ch);
					break;
				}
				//比较当前符号ch和栈顶符号top的优先级
				char topch = s.top();//获取栈顶符号 
				//Priority:true:ch > topch   false:ch <= topch
				if (Priority(ch, topch))//ch > topch
				{
					s.push(ch);//入栈
					break;//结束,进行遍历字符串的下一个字符 
				}
				else//ch <= topch
				{
					s.pop();//出栈 
					if (topch == '(')//如果遇见),是要一直出栈的,直到遇见(为主 
						break;//左右括号不用入到result里面 
					result.push_back(topch);//输出 
				}
			}
		}
	}

	//如果符号栈还存留符号,直接输出到后缀表达式里面     + /
	while (!s.empty())
	{
		result.push_back(s.top());
		s.pop();
	}

	return result;
}

int main()
{
	cout << MiddleToEndExpr("(1+2)*(3+4)") << endl;
	cout << MiddleToEndExpr("2+(4+6)/2+6/3") << endl;
	cout << MiddleToEndExpr("2+6/(4-2)+(4+6)/2") << endl;
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值