栈的应用——中缀转后缀表达式

算法思想

初始化一个栈,用于保存暂时还不能确定运算顺序的运算符

从左到右处理各个元素,直到末尾。可能出现三种情况:

  1. 遇到操作数。直接加入后缀表达式。

  2. 遇到界限符。遇到“(”直接入栈;遇到“)”则依次弹出栈内运算符并加入后缀表达式,直到弹出“(”为止。注意:“)“不加入后缀表达式。

  3. 遇到运算符。依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若碰到“(”或栈空则停止。之后再把当前运算符入栈。

按上述方法处理完所有字符后,将栈中剩余的运算符依次弹出,并加入后缀表达式。

不带括号版

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

void process(string s){
	string ans;//存字符数据,即最终的后缀表达式
	stack<char> op;//符号栈
	s.push_back('+');
	for(int i=0;i<s.size();i++){
		if(s[i]>='a'&&s[i]<='z'){//如果是操作数,将操作数加入答案串中
			ans+=s[i];
		}
		else {//如果是操作符
		if(s[i]=='+'||s[i]=='-'){//如果是+、-,则看看符号栈的情况,若不为空,则将栈中符号先加入答案串中(因为+、-的优先级最低,就算遇到相同优先级的也是先处理前面的)
			while(!op.empty()){//如果符号栈不为空,注意这里是循环,将符号栈里面的元素全部弹出
				ans+=op.top();//取栈顶元素
				op.pop();//弹出栈顶元素
			}
		}
		else if(s[i]=='*'||s[i]=='/'){//如果是*、/,则看看符号栈的情况,若不为空,则将栈顶是否是比*、/优先级更高的符号,若是,则加入答案串中(即不是+和-就行)
			if(!op.empty()&&(op.top()!='+'&&op.top()!='-')){
				ans+=op.top();
				op.pop();
			}
		}
		else if(s[i]=='^'){//若是^,因为^的优先级最高,则看看符号栈的情况,若不为空,则将栈顶是否是同优先级的^,若是,则让其先加入答案串中
			if(!op.empty()&&op.top()=='^'){
				ans+=op.top();
				op.pop();
			}
		}
		op.push(s[i]);//将当前操作符加入符号栈
	}
	}
	cout<<ans<<endl;
}


int main(){
	string s;
	while(cin>>s){
		process(s);
	}
	return 0;
}

带括号版

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

void process(string s){
	string ans;
	stack<int> op;
	s.push_back('+');
	for(int i=0;i<s.size();i++){
		if(s[i]=='('){//若为左括号,则入栈
			op.push(s[i]);
		}
		else if(s[i]==')'){	//遇到右括号,则结算之前到(的运算,注意)不用入栈(易错)
		  while(!op.empty()&&op.top()!='('){//这里是个循环,确保将非空栈中(之后入栈的符号都结算完
			ans+=op.top();
			op.pop();
		}
		op.pop();//弹出左括号(记得!!!)
		}
		else{//最后一种情况,即不是左括号也不是右括号
			if(s[i]>='a'&&s[i]<='z'){//若是操作数,加入答案串
				ans+=s[i];
			}
			else{
			if(s[i]=='+'||s[i]=='-'){//若为+、-,则弹出非空栈中左括号之后的运算符
				while(!op.empty()&&op.top()!='(')//循环——一直弹,直到遇到(
					ans+=op.top();
					op.pop();
				}
			}
			else if(s[i]=='*'||s[i]=='/'){//若为*、/则看看栈顶元素,如果栈顶元素是比*、/优先级高或者相等的且不是左括号的运算符,则弹出
				if(!op.empty()&&op.top()!='+'&&op.top()!='-'&&op.top()!='('){
					ans+=op.top();
					op.pop();
				}
			}
			else if(s[i]=='^'){//若为^,则看看栈顶元素,如果栈顶元素是和^相等的且不是左括号的运算符,则弹出
				if(!op.empty()&&op.top()=='^'&&op.top()!='('){
					ans+=op.top();
					op.pop();
				}
			}
			op.push(s[i]);//将当前运算符入栈
		}
		}
	}
	cout<<ans<<endl;
}
int main(){
	string s;
	while(cin>>s){
		process(s);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值