中缀表达式与后缀表达式之间的相互转换

中缀表达式转换为后缀表达式的规则:

中缀表达式a + b*c + (d * e + f) * g,转换成后缀表达式为a b c * + d e * f  + g * +。中缀表达式转换为后缀表达式的过程需要用到,具体过程如下:

1)从左遍历中缀表达式,如果遇到操作数,直接将其输出。

2)如果遇到操作符“+”, “-”,“*”, “/”,

  • 如果栈为空,则将其压入到栈中;
  •  如果栈不为空,
    • 如果栈顶的操作符的优先级较高,或与之相等,则弹出栈顶的操作符并输出,继续比较,直到遇见优先级较低的操作符(或者栈为空)为止,再将刚才遇见的操作符压入栈中。
    •  如果栈顶操作符的优先级较低,则直接将遇到的操作符压入栈中。

3)如果遇到括号:

  • 如果遇到左括号“(”,直接将其压入栈中;
  • 如果遇到右括号“)”,则将栈里的操作符依次弹出并输出,直到遇到左括号为止(注意,左括号弹出并不输出)。

4)如果我们遍历到了中缀表达式的的末尾,而此时栈非空,则将栈中剩余的所有操作符依次弹出并输出。

需要说明的是,“(”")"的优先级最低,其次是“+”“-”,“*”“/”的优先级最高。

 

实例:

以中缀表达式a + b*c + (d * e + f) * g转换为后缀表达式a b c * + d e * f  + g * +为例:

      从左向右遍历中缀表达式:

  1. 遇到a,输出,此时的后缀表达式为 :a
  2. 遇到+,此时栈为空,将+直接压入栈中,此时栈中的元素为 :顶 + 底
  3. 遇到b,输出,此时的后缀表达式为:a b
  4. 遇到*,与栈顶操作符+比较,+的优先级较低,将*压入栈中,此时栈中的元素为:顶 * + 底
  5. 遇到c,输出,此时的后缀表达式为:a b c
  6. 遇到+,与栈顶操作符*比较,*的优先级较高,弹出*并输出;再与栈顶元素+比较,+的优先级与之相等,弹出+并输出,此时栈为空,将+压入栈中,此时栈中的元素为:顶 + 底,此时的后缀表达式为a b c * +;
  7. 遇到(,直接压入栈中,此时栈中的元素为 :顶 ( + 底
  8. 遇到d,输出,此时的后缀表达式为:a b c * + d
  9. 遇到*,与栈顶操作符(比较,(的优先级较低,将*压入栈中,此时栈中的元素为 :顶  * ( + 底
  10. 遇到e,输出,此时的后缀表达式为:a b c * + d e
  11. 遇到+,与栈顶操作符*比较,*的优先级较高,弹出*并输出;再与栈顶元素(比较,(的优先级较低,将+压入栈中,此时栈中的元素为 :顶  + ( + 底,此时的后缀表达式为:a b c * + d e *
  12. 遇到f,输出,此时的后缀表达式为:a b c * + d e * f
  13. 遇到),依次弹出栈顶元素并输出,直到遇到左括号(为止,(弹出并不输出,完成操作之后栈中的元素为 :顶 + 底,此时的后缀表达式为:a b c * + d e * f +
  14. 遇到*,此时栈为空,将*直接压入栈中,此时栈中的元素为 :顶  * + 底
  15. 遇到g,输出,此时的后缀表达式为:a b c * + d e * f g
  16. 中缀表达式遍历结束,此时栈中的元素为顶  * +  底,将栈中剩余的所有操作符依次弹出并输出,完成操作之后的后缀表达式为:a b c * + d e * f g * +

 

实现代码(C++):

#include <iostream>
#include <cstdio>
#include <string>
#include <stack>
using namespace std;
 
int Priority(char op) { //判断操作符的优先级
	if(op=='('||op==')')		return 1;
	else if(op=='+'||op=='-')	return 2;
	else if(op=='*'||op=='/')	return 3;
}
 
string transfer(string str) { //将中缀表达式转换为后缀表达式
	string _str=""; 
	stack<char> s;
	int i=0;
	while(str[i]!='\0') {
		if(str[i]-'0'>=0&&str[i]-'0'<=9) //扫描到的是数字
				_str+=str[i];
		else {	//扫描得到的是操作符
			if(str[i]!='('&&str[i]!=')') {	//操作符非括号
				if(s.empty()) //如果栈是空的
					s.push(str[i]);
				else{ //如果栈不为空
                    int p=Priority(str[i]); 
					if(p>Priority(s.top())) //如果遇到的操作符的优先级,大于栈顶操作符的优先级
						s.push(str[i]); 
					else { //如果遇到的操作符的优先级,小于或等于栈顶操作符的优先级
						char temp;
						while((!s.empty())&&(p<=Priority(s.top()))){ //弹出栈顶操作符并输出,直到遇到的操作符的优先级大于栈顶操作符的优先级,或者栈为空
							temp=s.top();
							_str+=temp;
							s.pop();
                        }
                        s.push(str[i]);
					}
				}
			}
			else { //操作符是括号
				if(str[i]=='(') //如果操作符是左括号
					s.push(str[i]); 
				else { //如果操作符是右括号
					char temp=s.top();
					while(temp!='('){ 
						_str+=temp;
						s.pop();
						temp=s.top();
					}
					s.pop();
				}
			}
		}
		++i;
	}
	while(!s.empty()){ //将栈中剩余的操作符依次输出
		_str+=s.top();
		s.pop();
	}
	return _str;
}
 
int main() {
	string str="1+2*3+(4*5+6)*7";
	cout<<transfer(str)<<endl;
	return 1;
}
 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值