中缀表达式转化为后缀表达式是实现表达式计算的第一步。这里我给出了中缀表达式中数据为整数类型的转化,没有考虑浮点类型的转化。应用堆栈转化的基本过程:
1、遇到运算符直接输出
2、遇到左括号,压入堆栈
3、遇到右括号,将栈顶元素弹出,直到遇到左括号。不输出括号。
4、若遇到的运算符大于栈顶运算符优先级,则压入堆栈;否则,将栈顶弹出,直到该运算符大于栈顶优先级或者遇到左括号,然后将该运算符压入堆栈。
程序实现:首先要定义数据类型来存储输入的表达式(这个地方对于浮点运算不好处理),然后对于栈定义的数据类型应包括优先级。下面是我写的源代码,代码有点长。欢迎交流,写出更简洁的代码,注意每次测试前先输入回车。
/*
** 中缀表达式转化为后缀表达式
** 数据类型为整型
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode *List; /* 存储表达式链表 */
struct LNode{
char c;
List next;
};
typedef struct SNode *Stack; /* 存储运算符栈 */
struct SNode{
char opt; /* 运算符 */
int P; /* 优先级 */
Stack next;
};
List ReadInput();
void Print(List L);
void fun(List L);
Stack Create_Stack();
void Push(Stack S,char opt);
int Pority_Opt(char opt);
Stack Pop(Stack S);
int ISEmpty(Stack S);
int main()
{
List L;
while(getchar() != EOF)
{
L = ReadInput();
Print(L);
fun(L);
}
return 0;
}
List ReadInput()
{
List L,P,t;
char ch;
L = (List)malloc(sizeof(struct LNode));
P = L;
for(; (ch = getchar()) != EOF && ch != '\n';)
{
P->c = ch;
t = P;
P = (List)malloc(sizeof(struct LNode));
t->next = P;
}
free(P);
t->next = NULL;
return L;
}
void Print(List L)
{
List P=L;
if(L == NULL) printf("NULL\n");
for(; P != NULL; P = P->next)
printf("%c",P->c);
printf("\n");
}
/*
** 中缀表达式转后缀表达式
** 栈实现,只适用于整数表达式
*/
void fun(List L)
{
List P;
Stack S;
int Pt;
S = Create_Stack();
for(P = L; P != NULL; P = P->next)
{
if(P->c >= '0' && P->c <= '9')
printf("%c",P->c);
else{
printf(" ");
if( ISEmpty(S) ) /* 第一次运算符压栈 */
Push(S,P->c);
else{
if(Pority_Opt(P->c) > S->next->P && P->c != ')') /* 运算符优先级大于栈顶运算符优先级 */
Push(S,P->c); /* 压栈 */
else if(Pority_Opt(P->c) <= S->next->P){ /* 运算符优先级小于等于栈顶运算符优先级 */
while( !ISEmpty(S) && Pority_Opt(P->c) <= S->next->P && (S->next->opt - '(' != 0) ) /* 弹栈,一直到大于栈顶优先级 */
{ /* 或者遇到'(' */
Stack St = Pop(S);
printf("%c ",St->opt);
}
Push(S,P->c);
}
else{ /* 遇到 ')' */
Stack St = Pop(S);
while( !ISEmpty(S) && (St->opt - '(' != 0) ) /* 弹栈,一直到 '('*/
{
if(St->opt != '(') printf("%c ",St->opt);
St = Pop(S);
}
}
}
}
if( P->next == NULL && !ISEmpty(S) ){
Stack St = Pop(S);
printf(" %c ",St->opt);
}
}
}
/*
** 创建带有头结点的空栈
*/
Stack Create_Stack()
{
Stack S = (Stack)malloc(sizeof(struct SNode));
S->next = NULL;
return S;
}
/*
** 压栈
*/
void Push(Stack S,char opt)
{
Stack T = (Stack)malloc(sizeof(struct SNode));
T->opt = opt;
T->P = Pority_Opt(opt); /* 计算优先级 */
T->next = S->next;
S->next = T;
}
/*
** 计算运算符优先级
*/
int Pority_Opt(char opt)
{
switch(opt){
case '(': return 3;
case ')': return 3;
case '*': return 2;
case '/': return 2;
case '+': return 1;
case '-': return 1;
default: return 0; /* 错误 */
}
}
Stack Pop(Stack S)
{
Stack t=S->next;
if(ISEmpty(S)){
printf("空栈\n");
return NULL;
}
else{
S->next = t->next;
return t;
}
}
int ISEmpty(Stack S)
{
return S->next == NULL;
}