/*
栈采用顺序栈存储,试设计算法实现将表达式转换成后缀表达式输出。
例如,输入表达式: a+b/c-(d*e+f)*g
输出其后缀表达式: abc/+de*f+g*-
*/
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
typedef char SElemType;
typedef struct
{
char *base;
char *top;
int stacksize;
}SqStack;
Status InitStack(SqStack &S);
Status Push(SqStack &S, SElemType &e);
Status Pop(SqStack &S, SElemType &e);
Status GetTop(SqStack S, SElemType &e);
Status Matching(SqStack &S, char expression[]);
int StackLength(SqStack S);
int main(){
SqStack S;
InitStack(S);
printf("以下是表达式的转换");
char expression[] = "a+b/c-(d*e+f)*g";
printf("%s\n", expression);
Matching(S, expression);
return 0;
}
Status InitStack(SqStack &S){
S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if (!S.base)
{
exit(OVERFLOW);
}
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}
int StackLength(SqStack S){
// 返回栈中存储数据的部分的长度
return S.top - S.base;
}
Status GetTop(SqStack S, SElemType &e){
//空栈
if (S.top == S.base){
return ERROR;
}
//不可以用S.top - 1,因为这里只是读取,并非删除
e = *(S.top - 1);
return OK;
}
Status Push(SqStack &S, SElemType &e){
//栈满
if (S.top - S.base >= S.stacksize){
S.base = (SElemType *)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));
if (!S.base){
exit(OVERFLOW);
}
//指针的加减量实际上就是在地址上以对应的类型空间的移动
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
//e作为栈顶元素,先赋值,再向上移动
*S.top++ = e;
return OK;
}
Status Pop(SqStack &S, SElemType &e){
//栈空
if (S.top == S.base){
return ERROR;
}
//栈顶元素被忽略,读取后栈顶指针下移
e = *--S.top;
return OK;
}
Status Matching(SqStack &S, char expression[]){
//"a+b/c-(d*e+f)*g"
//abc/+de*f+g*-
int index, flag = 0;
char e;
for (index = 0; expression[index] != '\0'; index++){
switch (expression[index]){
case '+':
case '-':
flag = 1;
GetTop(S, e);
if (StackLength(S) == 0 || e == '(' ){
//入栈
Push(S, expression[index]);
break;
}
else{
//出栈
while (Pop(S, e)){
printf("%c ", e);
GetTop(S, e);
//栈空时退出循环
//出栈并不是全出,只在前面的优先级小的时候出,直到够大的时候,就push()
if (StackLength(S) == 0 || e == '('){
Push(S, expression[index]);
flag = -1;
break;
}
}
if (flag == 1){
Push(S, expression[index]);
}
break;
}
case '*':
case '/':
flag = 1;
GetTop(S, e);
if (StackLength(S) == 0 || e == '(' || e == '+' || e == '-'){
//入栈
Push(S, expression[index]);
break;
}
else{
//出栈
while (Pop(S, e)){
printf("%c ", e);
GetTop(S, e);
//栈空时退出循环
Push(S, expression[index]);
flag = -1;
break;
}
if (flag == 1){
Push(S, expression[index]);
}
break;
}
case '(':
flag = 1;
Push(S, expression[index]);
break;
case ')':
flag = 1;
if (StackLength(S)){
while (Pop(S, e)){
//栈空时退出循环
printf("%c ", e);
GetTop(S, e);
if (e == '('){
Pop(S, e);
break;
}
}
break;
}
else
return ERROR;
default:
printf("%c ", expression[index]);
}
}
if (StackLength(S) != 0){
while (Pop(S, e)){
printf("%c ", e);
}
}
return OK;
}
转换后缀表达式
最新推荐文章于 2021-04-14 15:37:27 发布