三、中缀表达式转后缀表达式
例如:
中缀表达式:123+5*21-7/(4-3)
后缀表达式:123 5 21 * + 7 4 3 / -
转换规则:
如果是数字,直接输出;
如果是左括号,直接入栈;
如果是右括号,一直出栈,直到遇到第一个左括号;
如果是*或者/,一直出栈,直到栈空或者左括号或者遇到+ -,当前符号入栈;
如果是+或者-,一直出栈,直到栈空或者遇到左括号,当前符号入栈;如果中缀表达式走完,弹出占中所有的元素
1、声明
#pragma once
//结构声明
typedef char ElemType;
//顺序栈实现
typedef struct Stack
{
ElemType *stack_low; //存储数据
int top; //栈顶
int size; //栈大小
}Stack;
//方法声明
//初始化
void InitStack(Stack* st, int init_size);
//判满
bool IsFull(Stack* st);
//判空
bool IsEmpty(Stack* st);
//开辟新空间,转移数据
static bool AppendNewSpace(Stack* st);
//入栈
bool Push(Stack* st, ElemType value);
//出栈
bool Pop(Stack* st);
//求栈顶元素
bool TopStack(Stack* st, ElemType* reval);
//销毁栈
void DestoryStack(Stack *st);
//打印栈中元素
void ShowStack(Stack* st);
//中缀转后缀
void InfixToSuffix(ElemType* ch, Stack* st);
2、方法实现
#include<stdio.h>
#include<stdlib.h>
#include"Middle_Rear.h"
#include<malloc.h>
#include<ctype.h>
//初始化
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->size = init_size;
st->top = 0;
}
//判满
bool IsFull(Stack *st)
{
if (st == NULL) return false;
return st->top == st->size;
}
//判空
bool IsEmpty(Stack* st)
{
if (st == NULL) return false;
return st->top == 0;
}
//开辟新空间,转移数据
static bool AppendNewSpace(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;
}
//入栈
bool Push(Stack* st, ElemType value)
{
if (st == NULL) return false;
//考虑是否栈满
if (IsFull(st))
{
AppendNewSpace(st);
}
st->stack_low[st->top] = value;
st->top++;
return true;
}
//出栈
bool Pop(Stack* st)
{
if (st == NULL) return false;
if (IsEmpty(st)) return false;
st->top--;
return true;
}
//求栈顶元素
bool TopStack(Stack *st,ElemType *reval)
{
if (st == NULL) exit(0);
//如果栈空
if (IsEmpty(st)) return false;
*reval = st->stack_low[st->top - 1];
return true;
}
//销毁栈
void DestoryStack(Stack* st)
{
if (st == NULL) exit(0);
while (!IsEmpty(st))
{
Pop(st);
}
free(st->stack_low);
st->stack_low = NULL;
st->size = st->top = 0;
}
//打印栈中元素
void ShowStack(Stack* st)
{
if (st == NULL) exit(0);
while (!IsEmpty(st))
{
printf("%c ", st->stack_low[st->top-1]);
Pop(st);
}
}
//中缀转后缀
void InfixToSuffix(ElemType* ch,Stack *st)
{
char top_elem;//存储栈顶元素
for (int i = 0; ch[i] != '\0'; i++)
{
//如果是数字就直接输出
if (isdigit(ch[i]))
{
if (isdigit(ch[i + 1]))
{
printf("%c", ch[i]);
}
else
{
printf("%c ", ch[i]);
}
continue;
}
//如果是'(',就执行入栈操作
if (ch[i] == '(')
{
Push(st, ch[i]);
continue;
}
//如果是')',就执行出栈操作,直到遇到第一个'('
if (ch[i] == ')')
{
while (1)
{
TopStack(st, &top_elem);
if (top_elem == '(')
{
Pop(st);
break;
}
Pop(st);
}
continue;
}
//如果是'*'或者'/',就是执行出栈操作,直到栈空或者栈顶元素是'+'或者'-'时,当前符号入栈
if (ch[i] == '*' || ch[i] == '/')
{
while (1)
{
TopStack(st, &top_elem);
if (top_elem == '+' || top_elem == '-' || IsEmpty(st))
{
Push(st, ch[i]);
break;
}
else
{
printf("%c ", top_elem);
Pop(st);
}
}
continue;
}
//如果是'+'或者'-',就执行出栈,直到栈空或者遇到'(',当前符号入栈
if (ch[i] == '+' || ch[i] == '-')
{
while (1)
{
TopStack(st, &top_elem);
if (top_elem == '(' || IsEmpty(st))
{
Push(st, ch[i]);
break;
}
else
{
printf("%c ", top_elem);
Pop(st);
}
}
continue;
}
}
}
3、主函数测试
#include<stdio.h>
#include"Middle_Rear.h"
int main()
{
char str[] = "123+5*21-7/(4-3)";
Stack space;//定义一个栈
InitStack(&space,10);//初始化栈
//中缀转后缀
InfixToSuffix(str,&space);
//中缀表达式走完,打印栈中余下元素
ShowStack(&space);
//最后销毁栈
DestoryStack(&space);
return 0;
}
4、测试结果
5、结束语
Doing things change things , no doing things , these things are exactly as they where.
行动才能改变,没有行动,一切也会原封不动。