C++堆栈应用(二):后缀表达式求值

本文介绍如何使用C++在CodeBlocks编辑器中实现后缀表达式的求值,包括解析后缀表达式、使用栈进行运算以及处理异常情况。代码基于《数据结构(第2版)》,涵盖GetOp()函数解析表达式和PostfixExp()函数求值的实现。

在日常生活中,我们接触到的算术表达式多为中缀表达式,其一般形式为:
5+6/2-3*4
即运算符位于两个参与运算的运算数的中间。
而在计算机对算术表达式求值时,却多是基于后缀表达式来进行求值。前面的中缀表达式转化为后缀表达式后,其形式为:
5 6 2 / + 3 4 * -
即运算符紧跟参与运算的两个运算数之后。

本文是关于如何在CodeBlocks编辑器中,用C++语言实现后缀表达式求值,所参考的代码来源于浙大陈越、何钦铭所编的《数据结构(第2版)》(高等教育出版社,2016),P71-81.
下文是对关键代码的阐释。

1.GetOp()函数:读入运算符或运算数
从后缀表达式中读入一个对象(运算数或运算符),并将其保存、返回。
GetOp()函数的三个形参参数:
1.char *Expr 是指向后缀表达式(一个字符数组)的字符指针;
2.int *index 是指示后缀表达式(字符数组)下标的整型指针;
3.char *str 是指向保存所读对象(运算数或运算符)的字符指针。

Type GetOp(char *Expr,int *index,char *str)
{
   
   
    int i=0;

    while((str[i]=Expr[(*index)++])==' '); //跳过后缀表达式前的空格
    while(str[i]!=' ' && str[i]!='\0'){
   
   
        str[++i]=Expr[(*index)++];  //将后缀表达式中的运算数或运算符存入str[]数组中
    }
    if(str[i]=='\0')
        (*index)--;  //如果读到后缀表达式的结尾,使下标停在结束符处
    str[i]='\0';   //写入结束标志

    if(i==0)                 //判断是否读到后缀表达式的结束
        return end;
    else if(isdigit(str[0])) //判断str[]中存入的是否为运算数
        return num;
    else                    //判断str中是否存的运算符
        return opr;
}

GetOp()函数的返回值为一个枚举类型的对象,该类型的定义为:

enum Type{
   
   num,opr,end};

类型名为Type,其中num,opr,end这三个枚举常量分别对应运算符、运算数、字符串结尾

2.PostfixExp()函数:调用GetOp()函数,读入后缀表达式并求值

ElementType PostfixExpr(char *Expr)
{
   
   
    Stack sta,*S;
    S=&sta;
    Type T;
    ElementType Op1,Op2;
    char str[MaxSize];
    int index=0;

    InitStack(S);
    Op1=Op2=0;
    /*当未读到结束标识符时*/
    while((T=GetOp(Expr,&index,str))!=end){
   
   
        if(T==num)  //如果读到运算数,存入栈顶
            Push(S,atof(str));

        else{
   
         //如果读到运算符,从栈中弹出最上面两个元素进行运算
            if(S->top!=-1)
                Op2=Pop(S);
            else
                Op2=INFINITY; //标记异常
            if(S->top!=-1)
                Op1=Pop(S);
            else
                Op2=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{
   
   
                        cout<<"错误:分母除法为0"<<endl;
                    }
                    break;
                }
                default
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值