中缀表达式转换为后缀表达式
三种方法:
-
借助堆栈:1. 如果是数字直接输出。 2. 如果是")",依次输出站内元素,只到输出"("。3. 如果是"(" 以及其他"+" 、"-" 、"*" 、"/"操作符。则与栈顶元素进行比较优先级;若前者较小,则连续出栈输出,直到前者大于后者,停止出栈。再将该操作符入栈。
优先级大小:如图
-
构造二叉树,后序输出:将表达式从左到右构造二叉树,"(" 与 ")"省略
-
加括号法:再不改变表达式结构的情况下尽可能多的增加括号,直至不能增加,然后从外向内依次将操作符提出括号外,同时去除括号
说了这么多上个例子
(a+b*c)/d+e*f
转换为后缀表达式
- 方法一:
- "("入栈, 此时 栈内情况:
(
输出:无
- "a"输出,此时 栈内情况:
(
输出:a
- "+"入栈,此时 栈内情况:
(+
输出:a
- "b"输出,此时 栈内情况:
(+
输出:ab
- "*"入栈,此时 栈内情况:
(+*
输出:ab
- "c"输出,此时 栈内情况:
(+*
输出:abc
- “)“栈内输出,直到”(”,此时 栈内情况:
空
输出:abc*+
- "/"入栈,此时 栈内情况:
/
输出:abc*+
- "d"输出,此时 栈内情况:
/
输出:abc*+d
- "+"栈内输出入栈,此时 栈内情况:
+
输出:abc*+d/
- "e"输出,此时 栈内情况:
+
输出:abc*+d/e
- "*"入栈,此时 栈内情况:
+*
输出:abc*+d/e
- "f"输出,此时 栈内情况:
+*
输出:abc*+d/ef
- 结束,栈内元素全部出栈输出,输出:
abc*+d/ef*+
-
方法二:
构造的二叉树如图所示:
按照:左子树,右子树,根的输出方式
后序遍历:abc*+d/ef*+
-
方法三:
- (a+bc)/d+ef
- (((a+(bc))/d)+(ef))
- ((a+(bc))/d)(ef)+
- (a+(bc))d/ef+
- a(bc)+d/ef+
- abc*+d/ef*+
做题的时候可以按照自己的习惯选择呀,编程的话,还是建议第一种借助堆栈
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <stack>
#include <string>
#include <queue>
using namespace std;
const int maxn = 1000+5;
typedef long long ll ;
char str[maxn];
//操作符入栈
stack<char> S;
//最后的结果
char ans[maxn];
int T, n;
int prority(char ch){
switch(ch){
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '(':
case ')':
return 0;
default :
return -1;
}
}
int main(){
scanf("%d",&T);
S.push('#');
while( T -- ){
scanf("%s",str);
n = 0;
for(int i=0; i<strlen(str); i++){
if( str[i] >= '0' && str[i] <= '9' ){//数字
ans[n++] = str[i];
} else if( str[i] == ')' ){// 右括号
while( S.top() != '(' ){//直到找到左括号
ans[n++] = S.top();
S.pop();
}
S.pop();//弹出左括号
} else if( str[i] == '(' ){
S.push(str[i]);//左括号入栈
} else{// + - * / 操作符的处理
if( prority(str[i]) > prority(S.top())){
S.push(str[i]);
} else{
while( prority(str[i])<=prority(S.top()) ){
ans[n++] = S.top();
S.pop();
}
S.push(str[i]);
}
}
}
while( S.top()!= '#' ){
ans[n++] = S.top();
S.pop();
}
ans[n] = '\0';
puts(ans);
}
return 0;
}