//后缀表达式求值
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include <stdbool.h>
#define MAXOP 100 //操作数列可能的最大长度
#define INFINITY 1e9 //正无穷
typedef double ElementType;//堆栈元素为double型
typedef enum{//枚举
num,opr,end
}Type;//运算数,运算符,字符串结尾
//顺序栈
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode {
ElementType *Data;//存储元素的数组
Position Top;//栈顶指针
int MaxSize;// 堆栈最大容量
};
typedef PtrToSNode Stack;
//1.创建
//创建一个给定容量的空堆栈
Stack CreateStack(int MaxSize)
{
Stack S=(Stack) malloc(sizeof(struct SNode));
S->Data =(ElementType *)malloc(sizeof(ElementType)*MaxSize);
S->Top =-1;
S->MaxSize =MaxSize;
return S;
}
//入栈push
/*
判断栈是否满,若不满,top+1,将新元素放入数组的top位置
*/
bool IsFull(Stack S)
{
return (S->Top ==S->MaxSize -1);
//满了返回true
}
bool Push(Stack S,ElementType X)
{
if(IsFull(S)){
printf("栈满\n");
return false;
}else {
S->Data [++(S->Top)]=X;//先+
return true;
}
}
//出栈pop
/*
判断栈是否为空
若不空,返回Data[Top],将top-1
否则返回一个ElementType类型的错误标志
*/
bool IsEmpty(Stack S)
{
return (S->Top ==-1);
//为空返回true
}
#define ERROR -1//ERROR为栈元素不可能取到的值
ElementType Pop(Stack S)
{
if(IsEmpty(S)){
printf("栈空\n");
return ERROR;
}else
return S->Data [(S->Top) --];
}
Type GetOp(char *Expr,int *start,char *str)
{
//从*start开始读入下一个对象(操作数或运算符),并保持在字符串str中
int i=0;
//跳过表达式前空格
while((str[0]=Expr[(*start)++])==' ');
while (str[i]!=' '&&str[i]!='\0')
str[++i]=Expr[(*start)++];
if(str[i]=='\0')//读到结尾
(*start)--; //*start指向结束符
str[i]='\0';//结束一个对象的获取
if(i==0)return end;//读到了结束
else if(isdigit(str[0])||isdigit(str[1]))//isdigit()检查其参数是否为十进制数字字符
return num;//表示str中存的是一个数字
else return opr; //表示此时str中存的是一个运算符
}
ElementType PostfixExp(char *Expr)
{
//调用GetOp函数读入后缀表达式并求值
Stack S;
Type T;
ElementType Op1,Op2;
char str[MAXOP];
int start=0;
//申请一个新堆栈
S=CreateStack(MAXOP);
Op1=Op2=0;
while((T=GetOp(Expr,&start,str))!=end){
//未读到结束
if(T==num)//运算数
Push(S,atof(str));//atof()把字符串转换成浮点数
else{//运算符
if(!IsEmpty(S))Op2=Pop(S);//运算数2
else Op2=INFINITY;
if(!IsEmpty(S))Op1=Pop(S);//运算数1
else Op1=INFINITY;
switch(str[0]){//计算入栈
case'+':Push(S,Op1+Op2);break;
case'-':Push(S,Op1-Op2);break;
case'*':Push(S,Op1*Op2);break;
case'/':
if(Op2!=0.0)Push(S,Op1/Op2);
else{
printf("错误:除法分母为0\n");
Op2=INFINITY;
}
break;
default:
printf("错误:未知运算符%s\n",str);
Op2=INFINITY;
break;
}
if(Op2>=INFINITY)break;
}
}
if(Op2<INFINITY)//表达式处理结束
if(!IsEmpty(S))//堆栈正常
Op2=Pop(S);//记录处理结果
else Op2=INFINITY;//否则标记错误
free(S);//释放堆栈
return Op2;
}
int main()
{
char Expr[MAXOP];
ElementType f;
gets(Expr);
f=PostfixExp(Expr);
if(f<INFINITY)//表达式正确
printf("%0.4f\n",f);
else
printf("表达式错误\n");
return 0;
}
运行: