中缀表达式转后缀表达式 ← C++实现

【算法分析】
简单而言,将中缀表达式转换为后缀表达式的算法需要注意以下两点。
● 操作数始终入操作数栈。
● 操作符入操作符栈时,比较与操作符栈的栈顶元素的优先级,然后选择入操作符栈还是入操作数栈。直至将操作符栈的所有元素入操作数栈后,终止算法。

若设操作符栈的栈顶元素为top,新来的操作符为new,则此步算法可形式化为:
if(new<=top) {pop top to 操作数栈, push new to 操作符栈}
if(new>top) {push new to 操作符栈}

注意:
上文中的top<=new,表示top的优先级小于等于new的优先级。top>new,以此类推。
当遇到左括号“(”时,直接入操作符栈。随后,在其之后出现的非右括号“)”的操作符的优先级都比它高,即可直接入操作符栈。
当遇到右括号“)”时,操作符栈的栈顶元素入操作数栈,然后左括号“(”出栈。

【实例分析】
例如,将中缀表达式 a+b-a*((c+d)/e-f)+g 转换为后缀表达式的过程如下。



事实上,熟悉算法规则之后,手推就可以很快搞定,不用像本例这样整这么长的解题过程。这在时间有限的考研考场特别重要。
之后,在熟悉各操作符的优先级后,再次提醒要特别注意本算法的核心规则:
(1)操作数始终入操作数栈。
(2)操作符入操作符栈时,比较与操作符栈的栈顶元素的优先级,然后选择入操作符栈还是入操作数栈。直至将操作符栈的所有元素入操作数栈后,终止算法。

【考研真题】

【研究生考试2012年第2题】操作符包括+-*/()。将中缀表达式a+b-a*((c+d)/e-f)+g转换为等价的后缀表达式ab+acd+e/f-*-g+时,用栈来存放暂时还不能确定运算次序的操作符,若栈初始时为空,则转换过程中同时保存在栈中的操作符的最大个数是(  A  )。
A. 5          B. 7          C. 8          D. 11


【研究生考试2014年第2题】假设栈初始为空,将中缀表达式 a/b+(c*d-e*f)/g 转换成等价的后缀表达式的过程中,当扫描到f时,栈中的元素依次是(  B  )。 
A. +(*-          B. +(-*          C. /+(*-*          D. /+-*


【算法代码】

#include <bits/stdc++.h>
using namespace std;

int prio(char op) {
	int grade;
	if(op=='*' || op=='/') grade=2;
	if(op=='+' || op=='-') grade=1;
	if(op=='(') grade=0;
	return grade;
}

string convert(string &in){
	string post;
	stack<char> s;
	for(int i=0; i<in.size(); i++){
		if(in[i]>='0' && in[i]<='9' || in[i]>='a' && in[i]<='z' || in[i]>='A' && in[i]<='Z'){
			post+=in[i];
		} 
		else {
			if(s.empty()) s.push(in[i]);
			else if(in[i]=='(') s.push(in[i]);
			else if(in[i]==')'){
				while(s.top()!='('){
					post+=s.top();
					s.pop();
				}
				s.pop();
			} 
			else {
				while(prio(in[i])<=prio(s.top())){
					post+=s.top();
					s.pop();
					if(s.empty()) break;
				}
				s.push(in[i]);
			}
		}
	}
	
	while(!s.empty()) {
		post+=s.top();
		s.pop();
	}
	
	return post;
}

int main() {
	string infix;
	cin>>infix;
	cout<<convert(infix)<<endl;
	
	return 0;
}


/*
in: a/b+(c*d-e*f)/g
out: ab/cd*ef*-g/+
*/


【参考文献】
https://www.jb51.net/article/241710.htm

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值