编译原理实验五---逆波兰表达式

一、实验目的与要求

将简单算术表达式转换为用逆波兰式,并计算用逆波兰式的值,加深对逆波兰式在代码编译中的用途。本实验只需要支持正数即可。

二、实验内容与方法

   任务1:简单表达式转换成逆波兰式的原则如下:设置一个输出队列,设置一个符号栈,为了处理方便,可以在输入简单表达式的最后加一个#,然后遍历表达式中的每个单元

1读取新单元。

2是数值,则放入队列中,回到第1步,不是则下一步。

3是操作符(+-*/()),如符号栈顶为空或栈顶操作符优先级比当前操作符优先级低,则直接将当前操作符压入符号栈,回到第1步;如果栈顶操作符和当前操作符优先级相等,则直接回到第1步(这种情况只发生在栈顶的左括号遇到当前的右括号的时候);其他情况将栈顶元素出栈,添加到队列,直到栈顶为空或者栈顶元素的优先级比当前操作符低,然后将当前操作符压入符号栈,回到第1步。

遍历结束后,将符号栈中剩余的符号都逐个弹出到输出队列中。此时输出队列中就是所要的逆波兰式。逆波兰式是不需要保存括号的。

优先级关系参看课本P157的表5.2,纵向为栈顶字符,横向为当前字符。

任务2:逆波兰式计算的原则如下:设置一个输出栈,从左到右遍历逆波兰式

  1. 如果是数字,则压入输出栈
  2. 如果是(+-*/),则从输出栈弹出两个操作数,和操作符计算后,将结果压入输出栈

遍历完成后输出栈中的数值就是计算的数值。

计算值用double类型存储和输出。

三、实验步骤与过程

1.编写getPriority函数,定义运算符的优先级

2.编写infixToRPN函数,返回原式的逆波兰式

   (1)定义一个operators的栈来保存运算符和左括号,

将数字或小数点直接输出到逆波兰式字符串

(2)当遇到右括号 ')' 时,需要将栈中与之对应的左括号 '(' 之前的所有运算符依次弹出,并加入到逆波兰式中。因此,while 循环的目的是将栈中的运算符弹出,直到遇到左括号为止。

在 while 循环结束后,栈顶的元素应该是左括号 '(',

因此需要再次执行 operators.pop() 将左括号弹出栈,完成括号的处理。

这样可以保证在转换过程中正确处理括号的匹配

(3)首先,通过 getPriority(operators.top()) 和 getPriority(c) 来比较当前运算符与栈顶运算符的优先级。如果栈顶运算符的优先级大于等于当前运算符,则需要将栈顶运算符弹出,并将其加入到逆波兰式中。

通过 while 循环,可以连续弹出栈顶的运算符,直到栈顶运算符的优先级小于当前运算符的优先级,或者栈为空。

最后,将当前运算符压入栈中,并在逆波兰式中添加一个空格,以分隔不同的运算符和操作数

3.编写evaluateRPN函数,计算逆波兰式的结果

定义一个operands的栈用来存放存放数字

后面遇到运算符的时候再从栈顶拿出数字进行计算

 运行截图:

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值