中缀表达式转前缀或后缀

中缀转后缀:
初始化栈s,s表示符号栈,用来存放中间符号

    步骤:
  • 从前往后依次循环处理每个字符
  • 若当前字符为操作数(数字或字母),直接输出(后缀表达式中操作数顺序与原序相同)
  • 若当前字符为运算符或括号,分三种情况处理
    • 若栈s为空或当前处理字符为左括号,直接入栈s
    • 若当前处理字符为右括号,s不断出栈(有个循环)输出,直到读到左括号,左括号直接舍弃
    • 其他情况则要比较当前处理字符和s栈顶字符的优先级
      • 若当前处理字符优先级,则入栈s
      • 其他情况(当前处理字符优先级小于等于栈顶字符优先级)s不断出栈(有个循环)并输出
  • 所有字符处理完,将栈s所有字符输出

中缀转前缀:
初始化两个栈s1,s2,s1表示符号栈,用来存放中间符号,s2用来存放前缀表达式。

    步骤:
  • 从后往前依次循环处理每个字符
  • 若当前字符为操作数(数字或字母),直接入栈s2
  • 若当前字符为运算符或括号,分三种情况处理
    • 若栈s1为空或当前处理字符为右括号,直接入栈s1
    • 若当前处理字符为左括号,s1不断出栈(有个循环)并入栈s2,直到读到右括号,右括号直接舍弃
    • 其他情况则要比较当前处理字符和s1栈顶字符的优先级
      • 若当前处理字符优先级大于等于栈顶字符优先级,则入栈s1
      • 其他情况(当前处理字符优先级低于栈顶字符优先级)s1不断出栈(有个循环)并入栈s2
  • 将栈s1中剩余字符不断出栈并入栈s2
  • 将栈s2元素依次输出即可

编程易错:
判断当前处理字符与栈顶字符优先级高低时,将栈非空的判断放在前面,否则栈空时会报错

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

int main(int argc, char *argv[]) {
	string str;
	map<char, int> priority;
	priority['+'] = 0;
	priority['-'] = 0;
	priority['*'] = 1;
	priority['/'] = 1;
	while(getline(cin, str)){
		stack<char> s1;//符号栈 
		stack<char> s2;
		char ch;
		int i;
		for(i = str.size() - 1; i >= 0; --i){
			if(('0' <= str[i] && str[i] <= '9') 
			|| ('a' <= str[i] && str[i] <= 'z') 
			|| ('A' <= str[i] && str[i] <= 'Z')){//数字直接入栈 
				s2.push(str[i]);
			}
			else{//运算符或括号 				
				if(s1.size() == 0 || str[i] == ')'){//栈空及字符为右括号直接入栈 
					s1.push(str[i]);
				}else if(str[i] == '('){//字符为左括号时不断出栈,直到右括号出栈,并进s2栈,括号舍弃 				    
					while(!s1.empty() && s1.top() != ')'){
						ch = s1.top();
						s1.pop();
						s2.push(ch); 
					}
					s1.pop();//右括号舍弃 
				}else{
					if(priority[str[i]] < priority[s1.top()]){//栈顶运算符优先级高 
						while(!s1.empty() && priority[str[i]] < priority[s1.top()]){//易错:要将栈非空的判断放在前面,否则在栈空时会报错 
							ch = s1.top();
							s1.pop(); 
							s2.push(ch);
						}
						s1.push(str[i]);
					}else{
						s1.push(str[i]);
					}
				}
			}
		}
		while(!s1.empty()){//符号栈剩余符号压入s2栈中 
			ch = s1.top();
			s1.pop();
			s2.push(ch);
		}
		while(!s2.empty()){
			ch = s2.top();
			s2.pop();
			cout<<ch;
		}
		cout<<endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值