题目描述
后缀表达式不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:(2 + 1) * 3 , 即2 1 + 3 *。利用栈结构,将后缀表达式的结果计算出来。
输入
后缀表达式。以#号作为表达式结束标志。为了简单,处理的数据为0-9的整数。
输出
计算结果。
样例输入
3 6 6 2 / - 3 * +#
样例输出
12
算法思想:
1.设置一个堆栈存放操作数
2.从左向右依次扫描后缀表达式
3.每读到一个操作数就进栈
4.每读到一个运算符就从栈顶取出两个操作数施以该运算符所表达的运算操作,并把其结果作为一个新的操作数入栈
5.循环以上过程直到后缀表达式读完,最后栈顶的操作数就是该后缀表达式的运算结果。
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#define Max 1000
typedef struct lnode
{
int data;
struct lnode *next;
}Lstack;
void Initstack(Lstack *&S)//初始化
{
S=(Lstack *)malloc(sizeof(Lstack));
S->next=NULL;
}
void Pushstack(Lstack *&S,int x)//进栈
{
Lstack *p;
p=(Lstack *)malloc(sizeof(Lstack));
p->data=x;
p->next=S->next;
S->next=p;
}
int Popstack(Lstack *&S,int *d)//出栈
{
Lstack *p=S->next;
if(p==NULL)
return 0;
else
{
S->next=p->next;
*d=p->data;
free(p);
}
}
int Postexp(char a[])//借助栈计算后缀表达式a的值
{
int x,x1,x2;
Lstack *S;//定义头指针变量
Initstack(S);
for(int i=0;a[i]!='#';i++)//循环直到输入'#'
{
if(a[i]==' ')//因为样例中有空格符
continue;
else if(isdigit(a[i]))
{
x=(int)(a[i]-48);//输入a[i]是字符串,要把它转换成int 型存入变量x中,48对应ASCII码表里的0,a[i]也会转化为ASCII码表里的数字
Pushstack(S,x);
}
else//当a[i]为运算符时
{
Popstack(S,&x2);//退栈得到操作数,存入变量x2中
Popstack(S,&x1);//退栈得到操作数,存入变量x1中(注意x1和x2的退栈次序)
switch(a[i])//执行a[i]所表示的运算
{
case'+':{x1+=x2;break;}
case'-':{x1-=x2;break;}
case'*':{x1*=x2;break;}
case'/':
if(x2==0.0)
return 0;
else
{
x1/=x2;
break;
}
}
Pushstack(S,x1);//将一次运算结果入栈
}
}
Popstack(S,&x);//得到最终运算结果,存入x中
return x;//返回x
}
int main()
{
int result;
char a[Max];
for(int i=0;;i++)
{
scanf("%c",&a[i]);
if(a[i]=='\n')//注意输入
break;
}
result=Postexp(a);
printf("%d",result);
}