代码来源 :
bilibili网站 :https://www.bilibili.com/video/av91996256?from=search&seid=17449723308302029804
注意:中缀表达式 转 后缀表达式,函数 有误。
中缀表达式 计算过程 :
后缀表达式 计算过程 :
中缀表达式 转 后缀表达式 :
/* 前缀:prefix
** 中缀:Infix
** 后缀:Suffix
exit为C++的退出函数,声明于stdlib.h中,对于C++其标准的头文件为cstdlib,
声明为 void exit(int value);
exit的功能为,退出当前运行的程序,并将参数value返回给主调进程。
在main中return v;的效果 与exit(v);相同。
exit(1)和exit(-1)是分别返回1和-1到主调程序。
exit(0): 返回0,表示程序正常退出,非0表示非正常退出。
exit(1):表示异常退出。
*/
#include <stdio.h>
#include <stdlib.h>
// #include <cstring>
#include <string.h>
enum boolean
{
FALSE,
TRUE
};
typedef enum boolean Bool; //枚举方式进行重定义
typedef int ElementType;
struct stack
{
ElementType *element;
int MaxSize; //大小
int top; //线性表:长度; 栈:栈顶指针
};
typedef struct stack Stack;
//需要的函数
void InitStack(Stack *S, int sz); //初始化函数
void FreeStack(Stack *S); //释放栈空间(即: 空间无)
Bool Push(Stack *S, ElementType X); //压栈
ElementType Pop(Stack *S); //弹栈(栈顶弹出)
ElementType GetTop(Stack *S); // 获取栈顶元素
void MakeStackEmpty(Stack *S); //置空(无元素,空间依然存在)
Bool IsStackEmpty(Stack *S); //栈是否为空
Bool IsStackFull(Stack *S); //栈是否为满
void EvaluteMidPostfix(); //中缀表达式求值
void EvaluteBackPostfix(); //后缀表达式求值
void MidToBack(); //中缀转后缀
int main()
{
//printf("%d\n", (int)('9' - 48));
//EvaluteMidPostfix();
EvaluteBackPostfix();
//MidToBack();
return 0;
}
//实现各个功能函数
void InitStack(Stack *S, int sz) //初始化栈(栈为空)
{
S->MaxSize = sz;
S->top = -1; //指向-1; 一个元素:指向0
S->element = (ElementType *)malloc(sizeof(ElementType) * S->MaxSize);
}
void FreeStack(Stack *S) //释放栈空间(即: 空间无)
{
free(S->element); //释放元素
}
Bool IsStackFull(Stack *S) //栈是否为满
{
// return S->top == S->MaxSize-1;
if (S->top == S->MaxSize - 1)
return TRUE;
return FALSE;
}
Bool IsStackEmpty(Stack *S) //栈是否为空
{
//return S->top == -1;
if (S->top == -1)
return TRUE;
return FALSE;
}
Bool Push(Stack *S, ElementType x) //压栈
{
//先判断 栈满?
if (IsStackFull(S))
return FALSE;
else
{
//指针指向新的栈顶
S->element[++S->top] = x; //top先加一
return TRUE;
}
}
ElementType Pop(Stack *S) //弹栈(栈顶弹出)
{
if (IsStackEmpty(S))
{
//return FALSE;
exit(1); //表示异常退出
}
else
{
//先弹出元素,指针下移
return S->element[S->top--];
}
}
ElementType GetTop(Stack *S) // 获取栈顶元素
{
if (IsStackEmpty(S))
{
//return FALSE;
exit(1); //表示异常退出
}
else
{
//先弹出元素,指针下移
return S->element[S->top];
}
}
void MakeStackEmpty(Stack *S) //置空(无元素,空间依然存在)
{
S->top = -1;
}
//从操作数栈取两个操作数;从操作符栈取一个操作符
//用操作符对操作数进行运算。将计算结果压入操作数栈。
void compute(Stack *Sptr, Stack *Spnd) //定义计算过程
{
int k;
switch (Pop(Sptr))
{
case '+':
k = Pop(Spnd) + Pop(Spnd);
break;
case '-':
k = Pop(Spnd);
k = Pop(Spnd) - k;
break;
case '*':
k = Pop(Spnd) * Pop(Spnd);
break;
case '/':
k = Pop(Spnd);
k = Pop(Spnd) / k;
break;
}
Push(Spnd, k); //将计算结果压入操作数栈。
}
void EvaluteMidPostfix() //中缀表达式计算求值
{
char buf[80];
printf("Please input Infix : \n");
scanf("%s", buf);
//strcpy_s(buf, 80, "8-(3+5-4/2)*2/3");
Stack *Spnd = (Stack *)malloc(sizeof(Stack));
Stack *Sptr = (Stack *)malloc(sizeof(Stack));
InitStack(Spnd, 80);
InitStack(Sptr, 80);
int i = 0;
while (buf[i] != '\0')
{
//操作数类型
if (buf[i] >= '0' && buf[i] <= '9')
Push(Spnd, (int)(buf[i] - 48)); //printf("%d",(int)('9'-48));
//操作符类型
//优先级最高(若无括号&&之后也是*或/,从左到右计算)
else if (buf[i] == '*' || buf[i] == '/')
{
// if(Sptr->top == -1 || GetTop(Sptr)=='(')//操作符直接入栈的条件
// Push(Sptr,buf[i]);
if (GetTop(Sptr) == '*' || GetTop(Sptr) == '/')
{
compute(Sptr, Spnd);
}
Push(Sptr, buf[i]);
}
else if (buf[i] == '+' || buf[i] == '-')
{
while (Sptr->top != -1 && GetTop(Sptr) != '(') //判断语句不可交换位置。
{
compute(Sptr, Spnd);
}
Push(Sptr, buf[i]);
}
else if (buf[i] == ')')
{
while (GetTop(Sptr) != '(')
{
compute(Sptr, Spnd);
}
Pop(Sptr);
}
else if (buf[i] == '(')
{
Push(Sptr, buf[i]);
}
i++;
}
while (Sptr->top != -1) //结束条件: 操作符栈为空
compute(Sptr, Spnd);
printf("%d", Pop(Spnd));
}
void EvaluteBackPostfix() //后缀表达式计算求值
{
char buf[80];
printf("Please input Suffix : \n");
scanf("%s", buf);
Stack *Spnd = (Stack *)malloc(sizeof(Stack));
InitStack(Spnd, 80);
int i = 0, k;
while (buf[i] != '\0')
{
switch (buf[i])
{
case '+':
k = Pop(Spnd) + Pop(Spnd);
Push(Spnd, k);
break;
case '-':
k = Pop(Spnd);
k = Pop(Spnd) - k;
Push(Spnd, k);
break;
case '*':
k = Pop(Spnd) * Pop(Spnd);
Push(Spnd, k);
break;
case '/':
k = Pop(Spnd);
k = Pop(Spnd) / k;
Push(Spnd, k);
break;
default:
Push(Spnd, (int)(buf[i] - 48));
}
i++;
}
printf("%d", Pop(Spnd));
}
void MidToBack() //中缀转后缀
{
char buf[80];
printf("Infix to suffix : \n");
scanf("%s", buf); // 读入中缀表达式
//strcpy_s(buf, 80, "8-(3+5-4/2)*2/3");
Stack *Sptr = (Stack *)malloc(sizeof(Stack));
InitStack(Sptr, 80);
int i = 0;
while (buf[i] != '\0')
{
//操作数类型
if (buf[i] >= '0' && buf[i] <= '9')
printf("%c", buf[i]);
//操作符类型
else if (buf[i] == '*' || buf[i] == '/')
{
if (IsStackEmpty(Sptr))
{
Push(Sptr, buf[i]); //栈空,往里放东西
}
else if (GetTop(Sptr) == '*' || GetTop(Sptr) == '/')
{
printf("%c", Pop(Sptr));
Push(Sptr, buf[i]);
}
else
{
Push(Sptr, buf[i]);
}
}
else if (buf[i] == '+' || buf[i] == '-')
{
if (IsStackEmpty(Sptr))
{
Push(Sptr, buf[i]); //栈空,往里放东西
}
}
else if (buf[i] == ')')
{
while (GetTop(Sptr) != '(')
{
printf("%c", Pop(Sptr));
}
Pop(Sptr);
}
else if (buf[i] == '(')
{
Push(Sptr, buf[i]);
}
i++;
}
while (Sptr->top != -1) //结束条件: 操作符栈为空
printf("%c", Pop(Sptr));
}
// 中缀:8-(3+5-4/2)*2/3 : 4
// 中缀:7+2*3/(2-3) : 1
// 后缀:234*+82/- : 10
// 中后:8-(3+5-4/2)*2/3 : 83542/-+2*3/- : 4
// 中后:2*(3+4)-8/2 : 234+*82/-
运行截图: