数据结构实验之栈三:后缀式求值

数据结构实验之栈三:后缀式求值

Time Limit: 1000MS Memory limit: 65536K

题目描述

对于一个基于二元运算符的后缀表示式(基本操作数都是一位正整数),求其代表的算术表达式的值。

输入

输入一个算术表达式的后缀式字符串,以‘#’作为结束标志。

输出

求该后缀式所对应的算术表达式的值,并输出之。

示例输入

59*684/-3*+#

示例输出

57

 

 

#include <stdio.h>
#include <stdlib.h>
#define stackmax 10000
#define stacknum 10000
typedef int ElemType;
typedef struct
{
    ElemType *base;
    ElemType *top;
    int stacksize;
} SqStack;

int InitStack(SqStack &s)
{
    s.base = (ElemType*) malloc (stackmax*sizeof(ElemType));
    if (! s.base)
        exit(0);
    s.top = s.base;
    s.stacksize = stackmax;
    return 0;
}
int Push(SqStack &s , int e)
{
    if(s.top-s.base >= s.stacksize)
    {
        s.base = (ElemType *)realloc(s.base,(s.stacksize+stacknum)*sizeof(ElemType));
        if (! s.base ) exit(0);
        s.top = s.base + s.stacksize;
        s.stacksize += stacknum;
    }
    *s.top++=e;
}
void putstack(SqStack &s)
{
    while(s.top > s.base)
    {
        printf("%d", *(s.top-1));
        s.top--;
    }
    printf("\n");
}


int  Pop(SqStack &s)
{
    if(s.top == s.base)   return 0;
    s.top--;
    return 1;
}

int GetTop(SqStack &s)
{
    if(s.top == s.base)   return 0;
    int e=*(s.top-1);
    return e;
}

int operate(int a, char theta, int b)
{
    int e;
    if(theta=='+')
        e=a+b;
    if(theta=='-')
        e=b-a;
    if(theta=='*')
        e=b*a;
    if(theta=='/')
        e=b/a;

    return e;

}//注意b与a的运算次序


int evaluation(SqStack &s, char c)
{
    int a, b;
    if(c>='0'&&c<='9')
    {
        Push(s, c-'0');
    }
    else
    {

        a=GetTop(s);
        Pop(s);
        b=GetTop(s);
        Pop(s);
        Push(s, operate(a, c, b));
    }


}

int main()
{
    char c;
    SqStack s;
    InitStack(s);
    while(~scanf("%c", &c)&&c!='#')
    {
        evaluation(s, c);
    }

    printf("%d", *s.base);
}

### 回答1: 是一种特殊的线性结构,后缀求值中需要用到。在后缀表达中,遇到操作数时将其压入中,遇到操作符时从顶取出两个操作数进行计算,将计算结果再压入中,直到最终得到表达的值。这种方法避免了操作符优先级的问题,也不需要括号,因此简化了计算过程。 ### 回答2: 后缀也称为逆波兰,是一种无需考虑运算符优先级也不需要括号即可确定完整运算顺序的表达表示方法。后缀的运算可以使用或队列的实现方。 在后缀求值的过程中,首先需要将中缀表达转换成后缀。具体操作为,从左到右扫描中缀表达,遇到操作数则输出到后缀中;遇到操作符时,判断其与顶操作符的优先级,如果该操作符优先级不高于顶操作符,则将顶操作符弹出并输出到后缀中,直到遇到顶操作符优先级比该操作符低或者相等时,再将该操作符入。如果遇到左括号,则直接将其入;如果遇到右括号,则将中左括号上面的操作符依次弹出并输出到后缀中,直到遇到左括号,左右括号不输出到后缀中。 将中缀表达转换成后缀之后,就可以根据后缀进行求值了。具体操作为,从左到右扫描后缀表达,遇到操作数则入;遇到操作符时,弹出顶的两个操作数,先弹出的作为右操作数,后弹出的作为左操作数,根据遇到的操作符进行计算,将结果入;最后扫描结束后,中仅有一个元素,即为表达的计算结果。 使用或队列的实现方均可以实现后缀求值,具体实现方也会略有不同。使用的实现方较为简单,只需要设置一个用于存储操作数和中间结果,按照后缀中的顺序进行遍历,遇到数字则压入中,遇到操作符时则弹出顶的两个数字进行计算并将结果压入中,最终中仅剩一个元素,即为表达的计算结果。 在实现代码时需要注意一些问题,如数字可能是多位数,需要处理好每一位;中缀表达中可能存在负数的情况,需要进行转换;在弹出顶元素时需要注意是否为空等等。 总之,与队列后缀求值数据结构实验中的一个重要实验,在实现过程中需要理解后缀的特点以及使用或队列实现后缀求值的具体过程,也需要注意在实现代码时处理好各种情况和异常情况,以保证程序的正确性和稳定性。 ### 回答3: 后缀是一种将算术表达中每个操作符都放在其相关操作数之后的形。例如,中缀表达“(5 + 4)× 3”可以转换为后缀表达“5 4 + 3 ×”。 在本实验中,我们需要实现一个后缀表达求值器,以计算给定的后缀表达的值。 实现该求值器的主要数据结构是一个。遍历后缀表达,如果遇到一个操作数,则将其压入中。如果遇到一个操作符,则弹出顶的两个操作数进行计算,并将结果压入中。最后,顶的元素就是后缀表达的值。 下面以‘5 4 + 3 ×’为例来说明该算法的具体步骤: 1. 从左到右依次遍历后缀表达,遇到5,将其压入中; 2. 遇到4,将其压入中; 3. 遇到+,弹出顶的两个元素4和5,计算5+4=9,将结果9压入中; 4. 遇到3,将其压入中; 5. 遇到×,弹出顶的两个元素9和3,计算9×3=27,将结果27压入中; 6. 最后中只剩下一个元素27,该元素即为后缀表达的值。 可以看出,后缀表达求值算法的时间复杂度为O(n),其中n是后缀表达的长度。 在实现算法时,还需要考虑以下一些问题: 1. 如何判断一个字符是操作符还是操作数? 2. 如何处理多位数字? 3. 如何处理负数? 4. 如何处理除0错误? 以上问题一一解决后,就可以完成后缀表达求值器的实现。通过实验,可以熟悉和队列的应用场景,加深对数据结构的理解,提高编程技能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值