数据结构实验之栈 后缀式求值(sdut oj2133)

本文介绍了如何对后缀表达式进行求值,详细阐述了求值过程,包括设置栈,从左到右扫描后缀表达式,遇到运算符时将操作数出栈进行运算,结果回栈,直至表达式结束。举例说明了后缀表达式如'1 2 + 8 2 - 7 4 - / *'的求值过程,解释了栈的变化,最终得出结果为6。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

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

输入

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

输出

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

示例输入

59*684/-3*+#

示例输出

57

提示


1 后缀表达式的求值
将中缀表达式转换成等价的后缀表达式后,求值时,不需要再考虑运算符的优先级,只需从左到右扫描一遍后缀表达式即可。具体求值步骤为:从左到右扫描后缀表 达式,遇到运算符就把表达式中该运算符前面两个操作数取出并运算,然后把结果带回后缀表达式;继续扫描直到后缀表达式最后一个表达式。 
例如,后缀表达式(abc*+def*/-) 的求值

2 后缀表达式的求值的算法
设置一个栈,开始时,栈为空,然后从左到右扫描后缀表达式,若遇操作数,则进栈;若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的 放到运算符左边,运算后的结果再进栈,直到后缀表达式扫描完毕。此时,栈中仅有一个元素,即为运算的结果。
例,求后缀表达式:1 2 + 8 2 - 7 4 - / * 的值, 
栈的变化情如下:

步骤

栈中元素

说明

1

1

1 进栈

2

12

2 进栈

3

 

遇+ 号退栈2 和1

4

3

1+2=3 的结果3 进栈

5

38

8 进栈

6

382

2 进栈

7

3

遇- 号退栈2 和8

8

36

8-2=6 的结果6 进栈

9

367

7 进栈

10

3674

4 进栈

11

36

遇- 号退栈4 和7

12

36

7-4=3 的结果3 进栈

13

3

遇/ 号退栈3 和6

14

32

6/3=2 的结果2 进栈

15

 

遇* 号退栈2 和3

16

6

3*2=6 进栈

17

6

扫描完毕,运算结束

从上可知,最后求得的后缀表达式之值为6 ,与用中缀表达式求得的结果一致,但后缀式求值要简单得多。
五、中缀表达式变成等价的后缀表达式的算法
将中缀表达式变成等价的后缀表达式,表达式中操作数次序不变,运算符次序发生变化,同时去掉了圆括号。转换规则是:设立一个栈,存放运算符,首先栈为空, 编译程序从左到右扫描中缀表达式,若遇到操作数,直接输出,并输出一个空格作为两个操作数的分隔符;若遇到运算符,则必须与栈顶比较,运算符级别比栈顶级 别高则进栈,否则退出栈顶元素并输出,然后输出一个空格作分隔符;若遇到左括号,进栈;若遇到右括号,则一直退栈输出,直到退到左括号止。当栈变成空时, 输出的结果即为后缀表达式。将中缀表达式(1+2)*((8-2)/(7-4)) 变成等价的后缀表达式。
现在用栈来实现该运算,栈的变化及输出结果如下:

步骤

栈中元素

输出结果

说明

1

(

 

( 进栈

2

(

1

输出1

3

(+

1

+ 进栈

4

(+

1 2

输出2

5

 

1 2 +

+ 退栈输出,退栈到( 止

6

*

1 2 +

* 进栈

7

*(

1 2 +

( 进栈

8

*((

1 2 +

( 进栈

9

*((

1 2 + 8

输出8

10

*((-

1 2 + 8

输出2

11

*((-

1 2 + 8 2

- 进栈

12

*(

1 2 + 8 2 -

- 退栈输出,退栈到( 止

13

*(/

1 2 + 8 2 -

/ 进栈

14

*(/(

1 2 + 8 2 -

( 进栈

15

*(/(

1 2 + 8 2 - 7

输出7

16

*(/(-

1 2 + 8 2 - 7

- 进栈

17

*(/(-

1 2 + 8 2 - 7 4

输出4

18

*(-

1 2 + 8 2 - 7 4 -

- 退栈输出,退栈到( 止

19

*

1 2 + 8 2 - 7 4 - /

/ 退栈输出,退栈到( 止

20

 

1 2 + 8 2 - 7 4 - / *

* 退栈并输出

 





基本操作数都是一位正整数!

来源

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;


int main()
{
    char aa, a[110];
    int ss[110];
    int top = -1;
    int k=0;
    while(scanf("%c", &aa)&&aa != '#')
    {
        a[k++] = aa;
    }
    for(int i = 0; i < k; i++)
    {
        if(a[i] >='0'&&a[i] <= '9')
        {
            ss[++top] = a[i]-'0';
        }
        else
        {
            int d = ss[top];
            int t = ss[top-1];
            if(a[i] == '*')
                ss[top-1] = t*d;
            else if(a[i] == '/')
                ss[top-1] = t/d;
            else if(a[i] == '+')
                ss[top-1] = t+d;
            else if(a[i] == '-')
                ss[top-1] = t-d;
            top--;
        }
    }
    printf("%d\n", ss[top]);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值