计算机软件实习项目一 简单计算器 (实验准备) 12-2

实验准备

一、需求分析

  概括来说简单计算器所要实现的主要功能为计算用户输入的算数表达式。主要有如下几点需要实现:

  1. 能够实现混合运算的求解,能够正确识别并处理"+"、"-"、"*"、"/"、"("、")" 等运算符,比较判断它们的优先级,按照正确的顺序对操作数进行运算,得出正确的计算结果。
  2. 设计并制作一个友好的GUI图形用户界面,用户能通过图形界面对表达式进行输入、修改、求值等操作,并且界面上能够显示出表达式的计算结果。
  3. 保存历史表达式的计算结果,供用户查看。
二、基本概念

中缀表达式

定义 一般我们生活中常见的表达式都为中缀表达式,例如:3 + 4 * 2 (a + b * c), 它是一个通用的算术或逻辑公式表示方法, 主要特点为操作符以中缀的形式处于操作数的中间,是人们常用的算术表示方法。

优点 符合人们的普遍用法,被许多程序语言使用。

缺点 中缀表达式不容易被计算机解析,这是由于中缀与前缀或后缀记法不同,中缀记法中括号是必需的。计算过程中必须用括号将操作符和对应的操作数括起来,用于指示运算的次序。


后缀表达式(逆波兰表达式)

定义 运算符放在运算项后面的逻辑表达式,主要特点为操作符以后缀的形式处于操作数之后,例如:3 4 2 * + (a + b * c)。

优点 符合人们的普遍用法,被许多程序语言使用。

缺点 中缀表达式不容易被计算机解析,这是由于中缀与前缀或后缀记法不同,中缀记法中括号是必需的。计算过程中必须用括号将操作符和对应的操作数括起来,用于指示运算的次序。

三、算法与数据结构

  有两种算法来解决计算算数表达式这个问题,一个是两步法,另一个是双栈算符优先级法,我们一个一个方法来看。

两步法

第一步:将中缀表达式转换为后缀表达式
1.从左到右扫描每一个字符。如果扫描到的字符是操作数(如a、b等),就直接输出这些操作数。
在这里插入图片描述
2. 如果扫描到的字符是一个操作符,分三种情况:
(1)如果堆栈是空的,直接将操作符存储到堆栈中(push it)
(2)如果该操作符的优先级大于堆栈出口的操作符,就直接将操作符存储到堆栈中(push it)
(3)如果该操作符的优先级低于堆栈出口的操作符,就将堆栈出口的操作符导出(pop it), 直到该操作符的优先级大于堆栈顶端的操作符。将扫描到的操作符导入到堆栈中(push)。
在这里插入图片描述在这里插入图片描述
3. 如果遇到的操作符是左括号"(”,就直接将该操作符输出到堆栈当中。该操作符只有在遇到右括号“)”的时候移除。这是一个特殊符号该特殊处理。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
4. 如果扫描到的操作符是右括号“)”,将堆栈中的操作符导出(pop)到output中输出,直到遇见左括号“(”。将堆栈中的左括号移出堆栈(pop )。继续扫描下一个字符
在这里插入图片描述
5. 如果输入的中缀表达式已经扫描完了,但是堆栈中仍然存在操作符的时候,我们应该讲堆栈中的操作符导出并输入到output 当中。
在这里插入图片描述
在这里插入图片描述
方法转自: 中缀表达式转后缀表达式


第二步:计算后缀表达式

计算后缀表达式又有两种方法,分别为堆栈法和二叉树法,我们分别讨论它们。

1. 堆栈法计算后缀表达式的值
1)从左到右扫描后缀表达式字符串
2)初始化一个空栈
3)如果扫描到数字,那么就直接入栈
4)如果被扫描的字符是一个二元运算符,那么就连续出栈两次,获得两个字符,元素出栈后,应用运算符进行计算,并将结果压栈
5)重复3)和4)的操作,直至扫描完字符串
6)扫描完所有字符串之后,栈中只剩一个元素,该元素就是最终结果,将其出栈并返回。

动画演示
方法转自:计算后缀表达式

2. 二叉树计算后缀表达式的值
  网上找了一些博客感觉还是实验提示ppt里写的清楚明了故引用ppt里的算法描述。
  此种方法逻辑结构上是一颗二叉树,实际物理结构则是用堆栈实现。二叉树的根节点/父节点都是操作符,叶子结点都是操作数。在这里插入图片描述
  通过从左至右遍历算数表达式,碰到一个操作数就创建一个结点并且入栈,碰到一个操作符就先取出一个操作数结点作为右孩子,再取出一个操作数结点作为左孩子,最后把这个操作符结点入栈,如此重复操作直到遍历完整个算数表达式,最后栈中剩下的就是表达式的树根节点。
在这里插入图片描述
在这里插入图片描述
方法来自:计算机软件技术实习-实验提示-江苏科技大学-王艳

双栈算符优先级法

预处理
1)建立两个栈:
一个是数据栈dataStak,用于存放数据;
一个是符号栈operatorStack,用于存放运算符;

符号优先级设置
1)(+ -)< (* /)
2) 相同运算符,栈内优先级高于栈外优先级
3) 对于栈内:左括号的优先级最高 右括号优先级仅高于’#’
4) 对于栈外:与上面相反

计算时机
1)当栈内运算符优先级 > 栈外运算符优先级:可以计算,计算结果压入数据栈
2)当栈内运算符优先级 < 栈外运算符优先级:栈外运算符压入运算符栈
3)当栈内运算符优先级 = 栈外运算符优先级:只可能是左括号和右括号的情况,将左括号出栈即可。
在这里插入图片描述
方法转自:双栈算术表达式求值算法

  比较两种算法其实它们的计算本质是一样的,第一种只是细化把中缀表达式转后缀表达式的过程和计算后缀表达式的过程分开了;第二种则是隐式地把两个步骤结合在了一起。
  我选择使用两步法作为此计算器的核心算法。

四、编程语言

C++
  在众多的编程语言当中我选择C++作为这个项目的编程语言,原因有其三。一是大学之前自学过一点C,它与C++有很大的相关性,加之上过C++程序设计课程,有一定的代码量积累,是我较为了解的一门语言。再者是C++能更好的兼容并支持QT框架,因为QT是一个完全的C++程序开发框架。次之是之前有过C++实现二叉树、排序树等的实践,捡起旧知识相对来说成本较低。故选择C++作为此项目的编程语言。

五、开发平台/工具

Visual Studio 2017
Qt Designer

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值