一、中缀表达式转换为后缀表达式
1.中缀表达式和后缀表达式
- 中缀表达式是符合人类正常逻辑思维的;
- 后缀表达式则是比较契合计算机的运算。
2.中缀表达式转换为后缀表达式
思考:我们要如何将(1-2)*(4+5)转换为1 2 - 4 5 + *呢?
提示:利用栈的“记忆”,符号都推入栈即可!
案例:1+ (2-3) * 4 + 10/5
(1)首先遇到第一个输入是数字1,数字在后缀表达式中都是直接输出,接着是符号"+",入栈:
(2)第三个字符是"(",依然是符号,入栈,接着是数字2,输出,然后是符号"-",入栈:
(3)接下来是数字3,输出,紧跟着是")",此时,我们需要去匹配栈里的"(",然后再匹配前将栈顶数据依次出栈(这就好比括号里优先执行的道理),将"("和"-"出栈,并输出"-":
(4)紧接着是符号"*",直接入栈:
(5)遇到数字4,输出,之后是符号"+",此时栈顶元素是符号"*",此时按照先乘除后加减的原理,此时栈顶的乘号优先级比即将入栈的加号要大,所以,先让栈内"*"出栈,再让"+"出栈,并依次输出,两个全出栈就为空栈了,再让4后面的"+"入栈:
(6)紧接着数字10,输出,最后是符号"/",进栈:
(7)最后一个数字5,输出,所有的输入处理完毕,但是栈中仍有数据,所以将栈中的符号依次出栈打印即可。
规则总结:从左到右遍历中缀表达式的每个数字和符号,若是数字则直接输出,若是符号,则判断其与栈顶符号的优先级,是右括号或是优先级低于栈顶符号,则栈顶元素依次出栈并输出,直到遇到左括号或栈空才将后一个符号入栈。
3.代码实现
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10
typedef char ElemType;
typedef struct{
ElemType *base;
ElemType *top;
int stackSize;
}sqStack;
// 创建一个栈
void InitStack(sqlStack *s){
s->base = (ElemType *)malloc(STACK_INIT_SIZE *sizeof(ElemType));
if(!s->base){
exit(0);
}
s->top = s->base;
s->stackSize = STACK_INIT_SIZE;
}
// 压栈
void Push(sqStack *s, ElemType e){
if(s->top - s->base >= s->stackSize){
s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT)*sizeof(ElemType));
if(!s->base){
exit(0);
}
}
*(s->top) = e;
s->top++;
}
void Pop(sqStack *s, ElemType *e){
if(s->top == s->base){
return;
}
*e = *--(s->top);
}
// 计算栈的当前容量
int StackLen(sqStack s){
return (s.top - s.base);
}
// 中缀表达式转换为后缀表达式
int main(){
sqStack s;
char c, e;
InitStack(&s);
printf("请输入中缀表达式,以#号作为结束标志:");
scanf("%c", &c);
while(c!='#'){
while(c>='0' && c<='9'){ // 循环输入解决多位数的输出问题,如果是数字直接打印
printf("%c", c);
scanf("%c", &c);
if(c<'0' || c>'9'){
printf(" ");
}
}
if(')' == c){ // 如果是右括号,就出栈,直到弹出第一个左括号为止
Pop(&s, &e);
while('(' != e){
printf("%c", e);
Pop(&s, &e)
}
}else if('+' == c || '-' == c){
if(!StackeLen(s)){ // 如果栈为空,直接入栈
Push(&s, c);
}else{ //如果栈不为空,先弹栈,比较优先级
do{
Pop(&s, &e);
if('(' == e){ // 如果弹栈的元素是左括号,则把左括号再入栈
Push(&s, e);
}else{ // 不是左括号,只能是+ - * / ,那么就把之前入栈的符号先打印出来
printf("%c ", e);
}
}while(StackLen(s) && '(' != e);
Push(&s, c); // 最后将新输入的+ -入栈
}
}else if('*' == c || '/' == c || '(' == c){
Push(&s, c)
}else if('#' == c){
break;
}else{
printf("\n出错:输入格式错误!\n")
}
scanf("%c", &c);
}
while(StackLen(s)){
Pop(&s, &e);
printf("&c ", e);
}
return 0;
}
本文为原创文章,如果对你有一点点的帮助,别忘了点赞哦!比心!如需转载,请注明出处,谢谢!