问题描述:
如何将中缀表达式转为后缀表达式,首先我们看看他们两者的联系与区别:
- 中缀表达式(或中缀记法)是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法。
- 但是,这种表达让计算机来做运算是不方便的,因此,有后缀表达式:
一个表达式E的后缀形式可以如下定义:
(1)如果E是一个变量或常量,则E的后缀式是E本身。
(2)如果E是E1 op E2形式的表达式,这里op是任何二元操作符,则E的后缀式为E1’ E2’ op,这里E1’和E2’分别为E1和E2的后缀式。
(3)如果E是(E1)形式的表达式,则E1的后缀式就是E的后缀式。
如:我们平时写a+b,这是中缀表达式,写成后缀表达式就是:ab+
原因分析:
我们很容易找到如何将中缀表达式转为后缀表达式,不过用栈怎么实现呢?
主要是处理下面这几种特殊情况即可:
代码实现:
#ifndef __STACK_H
#define __STACK_H
typedef char ElemType;
typedef struct Stack
{
ElemType *stack_low;
int top;
int size;
}Stack;
void InitStack(Stack *st, int init_size);
bool Empty(Stack *st);
bool Push(Stack *st, ElemType value);
bool Pop(Stack *st);
bool Top(Stack *st, ElemType *reval);
void DestroyStack(Stack *st);
#include "stack.h"
#include <string.h>
#include<stdio.h>
#include <stdlib.h>
#include<ctype.h>
static bool Full(Stack *st)
{
return st->top == st->size;
}
static bool AppendSpace(Stack *st)
{
ElemType *new_space = (ElemType*)malloc(sizeof(ElemType) * st->size * 2);
if(new_space == NULL) return false;
for(int i = 0; i < st->size; ++i)
{
new_space[i] = st->stack_low[i];
}
free(st->stack_low);
st->stack_low = new_space;
st->size *= 2;
return true;
}
void InitStack(Stack *st, int init_size)
{
if(st == NULL) exit(0);
init_size = init_size > 0 ? init_size : 10;
st->stack_low = (ElemType*)malloc(sizeof(ElemType) * init_size);
if(st->stack_low == NULL) exit(0);
st->top = 0;
st->size = init_size;
}
bool Empty(Stack *st)
{
if(st == NULL) exit(0);
return st->top == 0;
}
bool Push(Stack *st, ElemType value)
{
if(st == NULL) exit(0);
if(Full(st))
{
if(!AppendSpace(st))
{
return false;
}
}
st->stack_low[st->top++] = value;
return true;
}
bool Pop(Stack *st)
{
if(st == NULL) exit(0);
if(Empty(st)) return false;
st->top--;
return true;
}
bool Top(Stack *st, ElemType *reval)
{
if(st == NULL) exit(0);
if(Empty(st)) return false;
*reval = st->stack_low[st->top - 1];
return true;
}
void DestroyStack(Stack *st)
{
if(st == NULL) exit(0);
free(st->stack_low);
st->stack_low = NULL;
st->top = st->size = 0;
}
//中缀转后缀
void InfixToSuffix(char *str)
{
if(str==NULL) return;
Stack s;
InitStack(&s,10);
int i=0; //开始遍历表达式字符串的下标
while(str[i]!='\0')
{
if(str[i]==' ')
{
i++;
continue;
}
if(isdigit(str[i])) //如果是数字的情况
{
printf("%c",str[i]);
if(!isdigit(str[i+1]))
{
printf(" ");
}
}
else if(str[i]=='(') //如果是左括号的情况
{
Push(&s,str[i]);
}
else if(str[i]==')') //如果是右括号的情况
{
int flag=0;
while(!Empty(&s))
{
ElemType val;
Top(&s,&val);
Pop(&s);
if(val=='(')
{
flag=1;
break;
}
printf("%c ",val);
}
if(!flag)
{
printf("括号不匹配\n");
}
}
else if(str[i]=='*' || str[i]=='/')
{
ElemType val;
while(!Empty(&s))
{
Top(&s,&val);
if(val=='(' ||
val=='+' ||
val=='-') break;
Pop(&s);
printf("%c ",val);
}
Push(&s,str[i]);
}
else if(str[i]=='+' || str[i]=='-')
{
ElemType val;
while(!Empty(&s))
{
Top(&s,&val);
if(val=='(' ) break;
Pop(&s);
printf("%c ",val);
}
Push(&s,str[i]);
}
else
{
printf("输入内容有误!\n");
return;
}
i++;
}
while(!ElemType(&s))
{
ElemType val;
Top(&s,&val);
printf("%c ",val);
Pop(&s);
}
printf("\n");
DestroyStack(&s);
}
int main()
{
char str[]="12*4+34/5-(56+67*4)+32";
printf("\n");
InfixToSuffix(str);
return 0;
}