后缀表达式求值

//后缀表达式求值

#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;
}




 

运行:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值