中缀表达式变成后缀表达式
3+42/(5-4+1)
1、加括号 ( 3+((42)/ ((5-4)+1) ))
2、把符号放在括号外面 ( 3 ((4 2)* ((5 4)- 1) +)/)+
3、除去括号 3 4 2 * 5 4 - 1 +/+
转换过程需要用到栈,具体过程如下:
1)如果遇到操作数,我们就直接将其输出。
2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。
3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。
4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素 (或者栈为空) 为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到 " ) " 的情况下我们才弹出 " ( ",其他情况我们都不会弹出 " ( "。
5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。
#pragma once
/*********************************************************************************************************
运算符优先级,数值越小优先级越高
*********************************************************************************************************/
#define OPERA_PRIO_PLUS_IN 4 /* 栈内 + */
#define OPERA_PRIO_MINUS_IN 4 /* 栈内 - */
#define OPERA_PRIO_MULTIPLY_IN 2 /* 栈内 * */
#define OPERA_PRIO_DIVISION_IN 2 /* 栈内 / */
#define OPERA_PRIO_LEFT_BRACKETS_IN 10 /* 栈内 ( */
#define OPERA_PRIO_PLUS_OUT 5 /* 栈外 + */
#define OPERA_PRIO_MINUS_OUT 5 /* 栈外 - */
#define OPERA_PRIO_MULTIPLY_OUT 3 /* 栈外 * */
#define OPERA_PRIO_DIVISION_OUT 3 /* 栈外 / */
#define OPERA_PRIO_LEFT_BRACKETS_OUT 1 /* 栈外 ( */
#define OPERA_PRIO_RIGHT_BRACKETS_OUT 10 /* 栈外 ) */
#define OPERA_PRIO_ERR -1
#include <stdio.h>
#include <ctype.h>
#include "lstack.h"
#include "prio.h"
// 获取运算符的优先级
int Priority(char opera,bool InStack)
{
int prio=OPERA_PRIO_ERR;
if(InStack)
{
switch(opera)
{
case '+':
prio=OPERA_PRIO_PLUS_IN;
break;
case '-':
prio=OPERA_PRIO_MINUS_IN;
break;
case '*':
prio=OPERA_PRIO_MULTIPLY_IN;
break;
case '/':
prio=OPERA_PRIO_DIVISION_IN;
break;
case '(':
prio=OPERA_PRIO_LEFT_BRACKETS_IN;
break;
default:
prio=OPERA_PRIO_ERR;
break;
}
}
else
{
switch(opera)
{
case '+':
prio=OPERA_PRIO_PLUS_OUT;
break;
case '-':
prio=OPERA_PRIO_MINUS_OUT;
break;
case '*':
prio=OPERA_PRIO_MULTIPLY_OUT;
break;
case '/':
prio=OPERA_PRIO_DIVISION_OUT;
break;
case '(':
prio=OPERA_PRIO_LEFT_BRACKETS_OUT;
break;
case ')':
prio=OPERA_PRIO_RIGHT_BRACKETS_OUT;
break;
default:
prio=OPERA_PRIO_ERR;
break;
}
}
return prio;
}
//中缀表达式转为后缀表达式
void MidToLast(const char *mid,char *last)
{
SNode s;
InitStack(&s);
int prioIn;//栈内运算符优先级
int prioOut;//栈外运算符优先级
int tmp;
while(*mid!='\0')
{
if(isdigit(*mid))//数字字符直接存放在后缀表达式中
{
*last++=*mid++;
}
else//运算符
{
if(IsEmpty(&s))//栈空,直接进栈
{
Push(&s,*mid++);
}
else
{
prioOut=Priority(*mid,false);
GetTop(&s,&tmp);
prioIn=Priority((char)tmp,true);
if(prioOut<prioIn)//栈外优先级高,入栈
{
Push(&s,*mid++);
}
else if(prioOut>prioIn)//栈内优先级高,出栈
{
Pop(&s,&tmp);
*last++=(char)tmp;
}
else//括号匹配
{
mid++;
Pop(&s,NULL);
}
}
}
}
while(!IsEmpty(&s))
{
Pop(&s,&tmp);
*last++=(char)tmp;
}
*last='\0';
}
int main()
{
char *mid="3+4*2/(5-4+1)";
char last[100];
MidToLast(mid,last);
printf("mid=%s\nlast=%s\n",mid,last);
return 0;
}