//代码 3-5 中缀表达式转换为后缀表达式计算(simplified)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int ET; ET ERROR = 142857;
typedef struct {ET *data; int top; int maxSize;} Stack;
/* 调用基本操作 */
void InitStack(Stack *s, int maxSize);
void ClearStack(Stack *s);
int IsEmpty(Stack *s);
int IsFull(Stack *s);
int Push(Stack *s, ET e);
int Pop(Stack *s, ET *e);
ET GetTop(Stack *s);
//将中缀表达式转换为后缀表达式
void InfixToPostfix(char *infix, char *postfix, Stack *s){
int i = 0; char ch; ET e;
int isp[128] = {0}; int osp[128] = {0}; //优先级:(+-*/%) 加减乘余,1357,栈内为1栈外9
isp['('] = 1; isp[')'] = 7; isp['+'] = isp['-'] = 3; isp['*'] = isp['/'] = isp['%'] = 5;
osp['('] = 9; osp[')'] = 7; osp['+'] = osp['-'] = 3; osp['*'] = osp['/'] = osp['%'] = 5;
//只有左括号的优先级在栈内外是有区别
while (ch = *infix++){//依次读入
if (ch >= '0' && ch <= '9') postfix[i++] = ch; //操作数输出
else if (ch == '(') Push(s, ch); //左括号压栈
//右括号弹栈输出,直到左括号(弹出但不输出)
else if (ch == ')'){
while (GetTop(s) != '(') {Pop(s, &e); postfix[i++] = e;} Pop(s, &e);}
//以上皆非,则将该运算符的优先级和栈顶运算符的优先级做比较
else{//如果栈s非空,且ch的优先级 ≤栈顶元素的优先级,弹栈输出
while (!IsEmpty(s) && osp[ch] <= isp[GetTop(s)])
{Pop(s, &e);postfix[i++] = e;}
Push(s, ch);}} //否则ch压栈
//若中缀表达式已经扫描完毕,且栈非空,则将栈中存留的运算符一并输出
while (!IsEmpty(s)) {Pop(s, &e); postfix[i++] = e;} //弹出栈顶元素并输出
postfix[i] = '\0';} //字符串输出
//后缀表达式运算求值
int EvaluatePostfix(char *postfix, Stack *s){
char ch; ET op1, op2, res;
while(ch = *postfix++){//自左向右扫描后缀表达式,依次读入每一个字符ch
if (ch >= '0' && ch <= '9') Push(s, ch - '0'); //操作数压栈
else { //否则,ch是运算符
Pop(s, &op2); Pop(s, &op1); //弹出第2、第1个操作数
switch (ch){ //根据运算符进行运算,运算结果压回到栈中
case '+': Push(s, op1 + op2); break;
case '-': Push(s, op1 - op2); break;
case '*': Push(s, op1 * op2); break;
case '/': Push(s, op1 / op2); break;
case '%': Push(s, op1 % op2); break;}}}
Pop(s, &res); return res;} //从栈中弹出结果并返回
/* 主函数,记得复制基本操作 */
int main(){
int res; char infix[100], postfix[100]; Stack s; InitStack(&s, 100); //初始化栈s,栈容量设置为100
gets(infix); InfixToPostfix(infix, postfix, &s);
int i=0,n=strlen(postfix); for(i=0; i<n; i++) printf(i==n-1? "%c" : "%c ",postfix[i]);
ClearStack(&s); //清空栈s,为后续计算后缀表达式做准备
res = EvaluatePostfix(postfix, &s); printf("\n%d", res);} //输出计算结果
/* 记得复制基本操作 */
void InitStack(Stack *s, int maxSize){
s->data = (ET *)malloc(maxSize * sizeof(ET));
s->top = -1; s->maxSize = maxSize;}
void ClearStack(Stack *s) {s->top = -1;}
int IsEmpty(Stack *s) {if (s->top == -1) return 1; else return 0;}
int IsFull(Stack *s) {if (s->top >= s->maxSize - 1) return 1; else return 0;}
int Push(Stack *s, ET e) {if (IsFull(s)) return 0;
s->top++; s->data[s->top] = e; return 1;}
int Pop(Stack *s, ET *e) {if (IsEmpty(s)) return 0;
*e = s->data[s->top]; s->top--; return 1;}
ET GetTop(Stack *s){if (IsEmpty(s)) return 0;
return s->data[s->top]; }
中缀表达式转换为后缀表达式计算
于 2023-04-05 14:24:42 首次发布