1 、[问题描述] 输入一个中缀表达式,将其转换为后缀表达式,然后对后缀表达式进行求值。运算符包括“ + ”、“ - ”、“ * ”“ / ”、“(”“) ”、“#”,参加运算的数为小于10 的自然数。
2、[输入要求] 多组数据,每组数据一行,对应一个算术表达式,每个表达式均以“#”结尾。当表达式只有一个“#”时,输入结束。
3 、[输出要求] 对于每组数据输出 2 行,第一行为中缀表达式对应的后缀式,第2行为后缀求值的运算结果。
#include<stdio.h>
#define MAXSIZE 100
#define OK 1
#define ERROR 0
typedef char SElemType;
typedef int Status;
//栈的存储结构
typedef struct
{
SElemType *base; //栈底指针
SElemType *top; //栈顶指针
int stacksize; //栈的容量
}SqStack;
//顺序栈的初始化
Status InitStack(SqStack &S)
{
S.base = new SElemType[MAXSIZE]; //分配数组空间
if (!S.base)return ERROR; //存储分配失败
S.top = S.base; //top初始为base,空栈
S.stacksize = MAXSIZE; //栈的最大容量
return OK;
}
//判断栈满
Status Empty(SqStack S)
{
if (S.base == S.top)return OK;
else return ERROR;
}
//入栈
Status Push(SqStack &S, SElemType e)
{
if (S.top - S.base == S.stacksize - 1)return ERROR;//判满
*S.top++ = e; //元素e压入栈,栈顶指针加一
return OK;
}
//出栈
Status Pop(SqStack &S, SElemType &e)
{
if (S.base == S.top)return ERROR; //判空
e = *--S.top; //栈顶指针减一,栈顶元素赋给e
return OK;
}
//取栈顶元素
SElemType GetTop(SqStack S)
{
if (S.top != S.base) //判空
return *(S.top - 1);
}
//判断是否为运算符
Status In(char c)
{
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' || c == '#')return OK;
else return ERROR;
}
//判断运算符优先级
char Precede(char a, char b)
{
switch (a)
{
case '+':
switch (b)
{
case'+':return '>'; break;
case'-':return '>'; break;
case'*':return '<'; break;
case'/':return '<'; break;
case'(':return '<'; break;
case')':return '>'; break;
case'#':return '>'; break;
}
break;
case'-':
switch (b)
{
case'+':return '>'; break;
case'-':return '>'; break;
case'*':return '<'; break;
case'/':return '<'; break;
case'(':return '<'; break;
case')':return '>'; break;
case'#':return '>'; break;
}
break;
case'*':
switch (b)
{
case'+':return '>'; break;
case'-':return '>'; break;
case'*':return '>'; break;
case'/':return '>'; break;
case'(':return '<'; break;
case')':return '>'; break;
case'#':return '>'; break;
}
break;
case'/':
switch (b)
{
case'+':return '>'; break;
case'-':return '>'; break;
case'*':return '>'; break;
case'/':return '>'; break;
case'(':return '<'; break;
case')':return '>'; break;
case'#':return '>'; break;
}
break;
case'(':
switch (b)
{
case'+':return '<'; break;
case'-':return '<'; break;
case'*':return '<'; break;
case'/':return '<'; break;
case'(':return '<'; break;
case')':return '='; break;
case'#':return 'F'; break;
}
break;
case')':
switch (b)
{
case'+':return '>'; break;
case'-':return '>'; break;
case'*':return '>'; break;
case'/':return '>'; break;
case'(':return '>'; break;
case')':return 'F'; break;
case'#':return '>'; break;
}
break;
case'#':
switch (b)
{
case'+':return '<'; break;
case'-':return '<'; break;
case'*':return '<'; break;
case'/':return '<'; break;
case'(':return '<'; break;
case')':return 'F'; break;
case'#':return '='; break;
}
break;
}
}
//计算两个操作数
char Operate(char a, char b, char c)
{
char s;
a = a - '0'; c = c - '0'; //字符数字转为数字
if (b == '+')
s = a + c;
else if (b == '-')
s = a - c;
else if (b == '*')
s = a * c;
else if (b == '/')
s = a / c;
s = s + '0'; //数字再转为字符
return s;
}
//运算后缀表达式
char EvaluateExpression(SqStack S)
{
SqStack OPND; char ch,theta,a,b;
InitStack(OPND); //初始化OPND栈,存放操作数
while (Pop(S, ch)!=NULL) //S栈不为空
{
if (!In(ch)) //不是运算符,入栈OPND栈
Push(OPND, ch);
else
{
Pop(OPND, b); Pop(OPND, a); //出栈OPND
Push(OPND, Operate(a, ch, b)); //计算
}
}
return GetTop(OPND); //取栈顶元素
}
int main()
{
SqStack OPND, OPTR, S;
InitStack(OPND); InitStack(OPTR); InitStack(S); //初始化栈
char ch, theta, a, b, x,c;
//转为后缀表达式
Push(OPTR, '#'); //表达式起始符入栈
printf("输入一行字符以#结束:\n");
scanf_s("%c", &ch);
while (ch != '#' || GetTop(OPTR) != '#') //表达式没有扫描完成或OPTR的栈顶元素不为“#”
{
if (!In(ch)) //ch不是操作符
{
Push(OPND, ch); scanf_s("%c", &ch); //进栈,读取下一字符
}
else //比较运算符优先级
switch (Precede(GetTop(OPTR), ch))
{
case '<': //在栈运算符优先级小
Push(OPTR, ch); scanf_s("%c", &ch); //进栈,读取下一字符
break;
case '>': //在栈运算符优先级大
Pop(OPTR, a); //运算符从OPTR栈转如OPND栈
Push(OPND, a);
break;
case '=':
Pop(OPTR, x); scanf_s("%c", &ch); //在栈运算符(一般为‘(’)出栈,读取下一字符
break;
}
}
while (!Empty(OPND)) //取栈OPND中元素再压入S栈
{
Pop(OPND, b); Push(S, b);
}
//将后缀表达式运算
c = EvaluateExpression(S)-'0' ; //字符转为数字
printf("结果:%d\n", c); //输出结果
printf("后缀表达式:");
//将后缀表达式出栈输出
while (!Empty(S))
{
Pop(S, c);
printf("%c", c);
}
}