摘要:
(1)中缀表达式就是我们平常所说的计算表达式 如 1+2+3;
(2)后缀表达式就是将操作符号置于数的后面 1 2 + 3 +;
(将中缀表达式转换成后缀表达式的好处),计算机可以不用关心运算符号的优先级,直接按顺序读取。
(3)一个简单的算法用到数据结构:栈,将中缀表达式转换为后缀表达式:
{1}当读到一个操作数时,将它直接输出,当读到一个操作符号时,不将它输出,而是存放到栈里面。当遇到左括号(时也要放入栈中
{2}如果遇见一个右括号,就将它弹出(不输出),一直弹出操作符,直到遇见一个左括号(不输出)。
{3}如果遇见其他任何操作符,那么将检测它下面的符号优先级是否更低,如果是,则放入,如果不是,则一直弹出操作符,直到遇见优先级更低的符号为止。
{4}有一个例外,那就是弹出过程遇见一个“(”时,除非有“)”,否则不弹出“(”,(即弹出过程到此停止)。
{5}当确保入栈符号优先级最高后,再将其入栈。
(4)算法的分析,显然优先级高的操作符号总是位于栈的顶端,这也就意味着优先级高的总是先输出,那么计算机按顺序读入后缀也是符合中缀的优先级的。同时(,)保证了一个括号内的操作符与其他隔离开。
(5)注意的细节:{1}要注意处理小数点时的特殊情况(这会增加不少代码)。
{2}提前做好相关数据结构与优先级的定义.
{3}对幂运算要做单独的处理,因为它的优先级是从右到左的。(这也会增加不少代码)
// chap3_栈中缀后缀表达.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "malloc.h"
#include "stdlib.h"
#define EmptyTos -1
#define Left_bracket 50
#define Right_bracket 51
#define Power 45
#define Multiply 40
#define Divide 40
#define Plus 30
#define Subtract 30
typedef struct StackRecord *Stack;
struct StackRecord
{
int Cpapcity;
int TopStack;
char *Array;
};
void Push(Stack S,char X)
{
if(S->TopStack >= S->Cpapcity-1)
{
puts("cannot push an elements into a full stack");
return;
}
else
S->Array[++S->TopStack] = X;
}
char Pop(Stack S)
{
if (S->TopStack == EmptyTos)
{
puts("cannot Pop an empty stack");
exit(-1);
}
else
return(S->Array[S->TopStack --]);
}
void GetPriority(char Expression,int *ThisSymbol)//获取相应的优先级
{
switch(Expression)
{
case '+': *ThisSymbol = Plus;
break;
case '-': *ThisSymbol = Subtract;
break;
case '*': *ThisSymbol = Multiply;
break;
case '/': *ThisSymbol = Divide;
break;
case '^':*ThisSymbol = Power;
break;
case '(': *ThisSymbol = Left_bracket;
break;
case ')': *ThisSymbol = Right_bracket;
break;
default:
puts("there is wrong symbol");
return;
}
}
void Convert(Stack S,char *Expression)//中缀表达式变成后缀
{
int TopSymbol = 0;
int ThisSymbol = 0;
int k = 0;
char OutPut[100];
for(int i = 0;Expression[i] !='\0';i++)
{
if ((Expression[i]<='9'&&Expression[i]>='0')||Expression[i] == '.')
//处理数字
OutPut[k++] = Expression[i];
else
{ //处理操作符
GetPriority(Expression[i],&ThisSymbol);
//如果是空栈,先加入一个初始元素
if (S->TopStack == EmptyTos)
{
Push(S,Expression[i]);
TopSymbol = ThisSymbol;
continue;
}
//如果不是空栈,进行比较
if (ThisSymbol == Right_bracket)
//处理右括号
{
while(S->Array[S->TopStack]!='('&&S->TopStack !=EmptyTos)
{
OutPut[k++] = Pop(S);
}
if (S->TopStack ==EmptyTos)
{
//处理括号不匹配
puts("the brackets are not balanced");
return ;
}
//括号匹配,弹出‘(’
Pop(S);//弹出‘(’,但不输出
if (S->TopStack == EmptyTos)
{ //处理空的栈,将优先级设置为0.
TopSymbol = 0;
continue;
}
//处理不空的栈,将优先级设置为TOPSTACK的相应级别.
GetPriority(S->Array[S->TopStack],&TopSymbol);
}
else
//处理情况其他符号 <= 直到弹出优先级更低的符号
{
if (ThisSymbol > TopSymbol)
{//处理情况1
Push(S,Expression[i]);
TopSymbol = ThisSymbol ;
}
else
{
do
{
if(TopSymbol == Left_bracket)
{
//处理左括号
break;
}
else if (ThisSymbol == Power)//处理幂运算 ^,从右到左
{
if(ThisSymbol == TopSymbol)
break;
}
else
{ //处理 + - * / ( 从左到右
OutPut[k++] = Pop(S);
if(S->TopStack == EmptyTos)
break;
GetPriority(S->Array[S->TopStack],&TopSymbol);
}
}while (ThisSymbol <= TopSymbol);
//处理弹出后的元素,Push一下
Push(S,Expression[i]);
TopSymbol = ThisSymbol ;
}
}
}
}
while(S->TopStack != EmptyTos)
{
OutPut[k++] = Pop(S);
}
OutPut[k] = 0;
puts(OutPut);
return;
}
Stack CreateStack(int MaxElements)
{
Stack S;
S = (Stack)malloc(sizeof( StackRecord));
S->Array = (char*)malloc(sizeof(char)*MaxElements);
S->TopStack = EmptyTos;
S->Cpapcity = MaxElements;
return S;
}
int _tmain(int argc, _TCHAR* argv[])
{
char Expression[100] = {0} ;
Stack S;
S = CreateStack(100);
puts("Please input the expression");
scanf("%s", Expression);
Convert(S,Expression);
system("pause");
return 0;
}
结果实例: