前缀表达式&中缀表达式&后缀表达式

什么也不说先直接上题目:

算术表达式的转换

Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description

小明在学习了数据结构之后,突然想起了以前没有解决的算术表达式转化成后缀式的问题,今天他想解决一下。
   因为有了数据结构的基础小明很快就解出了这个问题,但是他突然想到怎么求出算术表达式的前缀式和中缀式呢?小明很困惑。聪明的你帮他解决吧。

Input

 输入一算术表达式,以\'#\'字符作为结束标志。(数据保证无空格,只有一组输入)

Output

 输出该表达式转换所得到的前缀式 中缀式 后缀式。分三行输出,顺序是前缀式 中缀式 后缀式。

Sample Input

a*b+(c-d/e)*f#

Sample Output

+*ab*-c/def
a*b+c-d/e*f
ab*cde/-f*+

由简入繁

1、中缀表达式:所谓中缀表达式就是运算符在操作数中间的表达式,所以只需将字符串去除括号原样输出即可。

2、前缀表达式(从右向左遍历):所谓前缀表达式就是操作符在前的表达式。操作数的相对顺序不变;

根据操作符的优先级来确定操作符输出的先后顺序。

算法:引入一个操作符栈op和运算栈outputs。从右向左遍历完整条字符串。

         1、如果为数字,则直接压入outputs栈中

         2、如果为当前字符为运算符(+-*/)则按照以下标准处理(只包含加减乘除运算符):

              2-1:如果op栈为空或者op的栈顶元素为')',则直接将当前的操作符压入op栈中。

              2-2:否则比较当前元素和栈顶元素的优先级,对op栈进行入栈或出栈造作。

                      2-2-1:如果当前元素优先级大于等于栈顶元素的优先级,则直接将此运算符入op栈。

                      2-2-2:反之将栈顶元素出栈并压入outputs栈中,直到当前运算符的优先级大于等于栈顶元素的优先级或者栈顶

                                 元素为')'或者栈为空。

         3、如果当前运算符为')'则直接入op栈。

         4、如果当前运算符为'('则弹出,直到遇见')'op栈中的所有运算符并依次压入outpus栈中 

                                                                                             (别忘了最后还要单独弹出')'!!!)。

         重复以上步骤直到整个字符串遍历完成。

         5、如果op栈非空,则将栈中所有的元素依次弹出压入outputs栈中。

         6、将outputs栈中的元素全部输出,便是前缀表达式。

3、后缀表达式(从左到右遍历):所谓前缀表达式就是操作符在后的表达式。操作数的相对顺序不变;

根据操作符的优先级来确定操作符输出的先后顺序。

算法:引入一个操作符栈op和运算向量空间outputs。从左向右遍历完整条字符串。

         1、如果为数字,则直接压入outputs向量中

         2、如果为当前字符为运算符(+-*/)则按照以下标准处理(只包含加减乘除运算符):

              2-1:如果op栈为空或者op的栈顶元素为'(',则直接将当前的操作符压入op栈中。

              2-2:否则比较当前元素和栈顶元素的优先级,对op栈进行入栈或出栈造作。

                      2-2-1:如果当前元素优先级大于(严格大于)栈顶元素的优先级,则直接将此运算符入op栈。

                      2-2-2:反之将栈顶元素出栈并压入outputs向量中,直到当前运算符的优先级大于(严格大于)栈顶元素的优先

                      级或者栈顶元素为')'或者栈为空。

         3、如果当前运算符为'('则直接入op栈。

         4、如果当前运算符为')'则弹出,直到遇见'('op栈中的所有运算符并依次压入outpus向量中 

                                                                                             (别忘了最后还要单独弹出'('!!!)。

         重复以上步骤直到整个字符串遍历完成。

         5、如果op栈非空,则将栈中所有的元素依次弹出压入outputs向量中。

         6、将outputs向量中的元素全部输出,便是后缀表达式。

干货代码(可能写的有点乱):

#include<stdio.h> 
#include<stack>
#include<iostream>
#include<string> 
#include<vector>
#define N 1001
using namespace std;
bool Checking(char topchar,char localchar){
	if(topchar==')'||topchar=='('){
		return true;
	} 
	else{
	    if(localchar=='+'||localchar=='-'){
	    	if(topchar=='+'||topchar=='-'){
			    return false;//当前元素与栈顶元素优先级一致 
		    }
		else{
			return false;
			//当前元素优先级低于栈顶元素 
		}
	}
	else{
		if(topchar=='+'||topchar=='-'){
			return true;
		}
		else
		    return false;
		//当前元素与栈顶元素优先级一致 
	}
	}
}
bool Checking2(char topchar,char localchar){
	if(topchar==')'||topchar=='('){
		return true;
	} 
	else{
	    if(localchar=='+'||localchar=='-'){
	    	if(topchar=='+'||topchar=='-'){
			    return true;//当前元素与栈顶元素优先级一致 
		    }
		else{
			return false;
			//当前元素优先级低于栈顶元素 
		}
	}
	else{
		return true;
		//当前元素与栈顶元素优先级一致 
	}
	}
}
int main(){
	int len=0;
	char str[N];//字符串 
	stack<char> op;//操作符栈
	stack<char> outputs;
	vector<char> outputs2;
	char c;
	cin>>c; 
	while(c!='#'){//获取中序表达式 
		str[len++]=c;
		cin>>c;
	}
	
	for(int i=len-1;i>=0;i--) {//前缀表达式,运算符在前,操作数在后 
		if(str[i]>='a'&&str[i]<='z'){
			outputs.push(str[i]);//如果是操作数放入输出栈中 
		}
		else if(str[i]!=')'&&str[i]!='('){
			if(op.empty()||op.top()==')'){
				op.push(str[i]);
			}
			else{
			    if(Checking2(op.top(),str[i])){//当前元素优先级比栈顶高 
			    	op.push(str[i]);
				}
				else{
					while(true){//当前元素优先级比栈顶低 
					    outputs.push(op.top()); 
						op.pop();
						if(op.empty()||op.top()==')'||Checking2(op.top(),str[i])){
							op.push(str[i]);
							break;
						}  
					}
				}
			}
		} 
		else if(str[i]==')'){
				op.push(str[i]);
		}
		else{
			while(op.top()!=')'){
				outputs.push(op.top());
				op.pop();
			}
			op.pop();
		}
	}
	while(!op.empty()){//判断操作符栈是否为空。将剩余元素压入输出栈中 
		outputs.push(op.top());
		op.pop();
	}
	while(!outputs.empty()){//逆序输出输出栈中元素的到前缀表达式 
		cout<<outputs.top();
		outputs.pop();
	}
	cout<<endl;
	for(int i=0;i<len;i++){//中缀表达式,只需去掉括号,操作符位于运算数之间 
		if(str[i]!=')'&&str[i]!='(')
		cout<<str[i];
	}
	
	cout<<endl;
	
	for(int i=0;i<len;i++) {//后缀表达式操作数在前,运算符在后 
	    if(str[i]>='a'&&str[i]<='z'){
			outputs2.push_back(str[i]);//如果是操作数放入输出栈中 
		}
		else if(str[i]!=')'&&str[i]!='('){
			if(op.empty()||op.top()=='('){
				op.push(str[i]);//如果栈空或者栈顶元素为左括号直接入栈 
			}
			else{//为运算符 
			    if(Checking(op.top(),str[i])){//当前元素优先级比栈顶高 
			    	op.push(str[i]);
				}
				else{
					while(true){//当前元素优先级比栈顶低 
					    outputs2.push_back(op.top()); 
						op.pop();
						if(op.empty()||op.top()=='('||Checking(op.top(),str[i])){
							break;
						}  
					}
					op.push(str[i]);
				}
			}
		} 
		else if(str[i]=='('){
				op.push(str[i]);
		}
		else{
			while(op.top()!='('){
				outputs2.push_back(op.top());
				op.pop();
			}
			op.pop();
		}
	}
	while(!op.empty()){//判断操作符栈是否为空。将剩余元素压入输出栈中 
		outputs2.push_back(op.top());
		op.pop();
	}
	for(int j=0;j<outputs2.size();j++){
		cout<<outputs2.at(j);
	}
	outputs2.clear();
	cout<<endl;
	return 0;
}
 

猜你喜欢

转载自blog.csdn.net/m0_37848958/article/details/80141078