实验三:算术表达式求解

一、需求分析

1.实现标准整数类型的四则运算表达式的求值(包含括号,可多层嵌入)。

2.能够检验输入的合法性,保证程序的稳定运行。

二、数据结构的选择和概要设计

1.中缀表达式转后缀表达式

后缀表达式

我们日常生活中使用的算术表达式,例如:5+6/2-3*4,它由两类对象构成:

  • 运算数,如:5,6,2等
  • 运算符号,如+,-等,而且不同运算符号优先级不一样

由于运算符号优先级不同,而且运算符号位于运算数中,所以使得运算变得复杂了。 怎么理解呢?拿上面的表达式为例,当程序遍历到+号的时候,要做+运算,那么是5+6吗?很显然不是,因为6后面还有一个/运算符,而且/的优先级大于+,所以6是/的运算数,而不是+的运算数。那么反过来呢?当遍历到一个运算符号的时候,就已经知道对应的两个运算数,这样求值就变的简单了。伟大的科学家们,就此发明了后缀表达式,也称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。

  • 中缀表达式:2 + 9 / 3 - 5
  • 后缀表达式:2 9 3 / + 5 -

当然两个表达式,都是表达同一个意思。

2.后缀表达式的计算

后缀表达式求值

由于后缀表达式不需要考虑运算符的优先规则,因此求值算法就变得简单了:

1、从左到右依次遍历表达式;

2、遇到数字就直接入栈;

3、遇到操作符就弹出两个元素,先弹出的元素放到操作符的右边,后弹出的元素放到操作符的左边(左边的运算数先入栈,因此后出),将计算得到的结果再压入栈;

4、直到整个表达式遍历完,最后弹出的栈顶元素就是表达式最终的值。

3.中缀表达式转后缀表达式

接下来看看中缀怎么转后缀,我们先对比一下两个表达式:

  • 中缀表达式:2 + 9 / 3 - 5
  • 后缀表达式:2 9 3 / + 5 -

可以看的出来,数字的相对位置是不变的,改变的是符号的位置,那么在转换的过程,我们需要对比各种运算符号的优先级,然后将优先级高的运算符,先输出,低的后输出,这样在后缀表达式求值的时候,就能保存计算顺序不被改变。(左括号和右括号也看成运算符号)具体的算法步骤如下:

1、从左到右遍历中缀表达式;

2、如果是运算数,直接输出;

3、如果是运算符号:若优先级大于栈顶的运算符号(栈不为空),则将该运算符号压入栈中,因为如果该运算符号优先级比栈顶的大,说明要先被计算,那么它是后入的,因此在之后的操作中,一定比栈顶的符号先出,因此在后缀求值中,肯定先被计算;

4、如果是运算符号:若优先级小于等于栈顶的运算符号(栈不为空),则将栈顶的运算符号弹出并输出,然后继续和下一个新的栈顶元素对比,直到优先级大于新的栈顶元素,就将该运算符号压入栈中;

5、左括号:括号里的表达式肯定是要先计算的,因此当扫描到左括号的时候,直接将左括号压入栈中,而入了栈里的左括号,优先级就变到最低了。因为括号里的运算符要先运算

6、右括号:将栈顶元素弹出并输入,直到遇到左括号(弹出,但不输出);

7、整个表达式遍历完之后,则将栈里的元素一一弹出并输出。

4.数据结构栈的实现

栈:LIFO(后进先出),自己实现一个栈,要求这个栈具有push()pop()(返回栈顶元素并出栈)、peek() (返回栈顶元素不出栈)、isEmpty()这些基本的方法。

参考自: 数据结构之栈——算术表达式求值 - 掘金

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值