什么也不说先直接上题目:
算术表达式的转换
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; }