计算机软件技术实习项目一(一) 简易计算器项目准备

计算机软件技术实习项目一(一) 简易计算器项目准备


前言

大家好,我将为大家介绍我学习计算器的准备知识,做软件是我之前没有接触过的领域做得不好,大家不要见怪。本文主要介绍简易计算器的相关知识,如果想看实现请结合《计算机软件技术实习项目一(二) 简易计算器项目实现》


一、简易计算器介绍

  简易计算器是可以实现运算加减乘除带括号的表达式的计算器。

二、开发工具

  编程语言:c++
  开发工具:Visual Studio 2019
  类库:MFC

三、实现原理

  我们在简易计算器中,要用到的是加减乘除四则运算功能,以及设计括号表达式优先级处理。
  计算方法有三种:1.后缀表达式计算法(3.3)、2.双栈算符优先级法(4)、3.用二叉树来求解后缀表达式的值(5).
  我们需要用到的数据结构有栈和二叉树。

1.栈

  我们在实现计算器功能的时候需要用到数据结构栈。
基本释义:
  栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
算法实现:
  (1)进栈(PUSH)算法
  ①若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);
  ②置TOP=TOP+1(栈指针加1,指向进栈地址);
  ③S(TOP)=X,结束(X为新进栈的元素);
  (2)退栈(POP)算法
  ①若TOP≤0,则给出下溢信息,作出错处理(退栈前先检查是否已为空栈, 空则下溢;不空则作②);
  ②X=S(TOP),(退栈后的元素赋给X):
  ③TOP=TOP-1,结束(栈指针减1,指向栈顶)。

2.优先级比较数组

  在计算表达式的时候,我们会遇到比较两个运算符的情况,所以我们需要写一个运算符的比较数组。
优先级比较数组

3.表达式

  计算器实现的原理相当于运用特殊的运算规则,去运算表达式。
  带括号的计算表达式,无法简单的按照运算符优先级来处理表达式;
如果,有这么一种表达式,把算术表达式按照运算符的计算顺序来表示的话,不再考虑运算符的优先规则,问题就变得简单易解了。
  后缀表达式:又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)

3.1前缀表达式

基本释义:
  前缀表达式就是前序表达式,是一种是由波兰数学家扬·武卡谢维奇1920年引入的数学表达式方式。例如,- 1 + 2 3,它等价于1-(2+3)。
求值方法:
  对前缀表达式求值,要从右至左扫描表达式,首先从右边第一个字符开始判断,若当前字符是数字则一直到数字串的末尾再记录下来,若为运算符,则将右边离得最近的两个“数字串”作相应运算,然后以此作为一个新的“数字串”并记录下来;扫描到表达式最左端时扫描结束,最后运算的值即为表达式的值。
  例如:对前缀表达式“- 1 + 2 3”求值,扫描到3时,记录下这个数字串,扫描到2时,记录下这个数字串,当扫描到+时,将+右移做相邻两数字串的运算符,记为2+3,结果为5,记录下5这个新数字串,然后继续向左扫描,扫描到1时,记录下这个数字串,扫描到-时,将-右移做相邻两数字串的运算符,记为1-5,结果为-4,此时关于这个表达式的全部运算已完成,故表达式的值为-4。

3.2中缀表达式

基本释义:
  (或中缀记法)是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法。
求值方法:
  按照正常的习惯计算即可;

3.3后缀表达式

  计算器求解的第一种方法就是中缀表达式转换乘后缀表达式(见3.4),然后再按照后缀表达式的计算方法来求。
基本释义:
  一个表达式E的后缀形式可以如下定义:
  (1)如果E是一个变量或常量,则E的后缀式是E本身。
  (2)如果E是E1 op E2形式的表达式,这里op是任何二元操作符,则E的后缀式为E1’E2’ op,这里E1’和E2’分别为E1和E2的后缀式。
  (3)如果E是(E1)形式的表达式,则E1的后缀式就是E的后缀式。
如:我们平时写a+b,这是中缀表达式,写成后缀表达式就是:ab+
(a+b)c-(a+b)/e的后缀表达式为:
(a+b)c-(a+b)/e
→((a+b)c)((a+b)/e)-
→((a+b)c
)((a+b)e/)-
→(ab+c
)(ab+e/)-
→ab+c
ab+e/-
求值方法:
  新建一个表达式,如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。
  接下来我将以图解的形式为大家进行演示。
  后缀表达式:9 3 1-3*+ 10 2/+
  1. 初始化一个空栈。此桟用来对要运算的数字进出使用。
  2. 后缀表达式中前三个都是数字,所以9、3、1进栈。
           在这里插入图片描述
  3. 接下来是减号“-”,所以将栈中的1出栈作为减数,3出栈作为被减数,并运算3-1得到2,再将2进栈。
          
  4. 接着是数字3进栈。
          在这里插入图片描述
  5. 后面是乘法“*”,也就意味着栈中3和2出栈,2与3相乘,得到6,并将6进栈。
  6. 下面是加法“+”,所以找中6和9出找,9与6相加,得到15,将15进栈。
          在这里插入图片描述
  7. 接着是10与2两数字进栈。
  8. 接下来是符号因此,栈顶的2与10出栈,10与2相除,得到5,将5进栈。
          在这里插入图片描述
  9. 最后一个是符号“+”,所以15与5出找并相加,得到20,将20进栈。
  10. 结果是20出栈,栈变为空。
          在这里插入图片描述

3.4中缀表达式转换成后缀表达式

算法实现:
  将一个普通的中缀表达式转换为逆波兰表达式的一般算法是:
  首先需要分配2个栈,一个作为临时存储运算符的栈S1(含一个结束符号),一个作为存放结果(逆波兰式)的栈S2(空栈),S1栈可先放入优先级最低的运算符#,注意,中缀式应以此最低优先级的运算符结束。可指定其他字符,不一定非#不可。从中缀式的左端开始取字符,逐序进行如下步骤:
  (1)若取出的字符是操作数,则分析出完整的运算数,该操作数直接送入S2栈。
  (2)若取出的字符是运算符,则将该运算符与S1栈栈顶元素比较,如果该运算符(不包括括号运算符)优先级高于S1栈栈顶运算符(包括左括号)优先级,则将该运算符进S1栈,否则,将S1栈的栈顶运算符弹出,送入S2栈中,直至S1栈栈顶运算符(包括左括号)低于(不包括等于)该运算符优先级时停止弹出运算符,最后将该运算符送入S1栈。
  (3)若取出的字符是“(”,则直接送入S1栈顶。
  (4)若取出的字符是“)”,则将距离S1栈栈顶最近的“(”之间的运算符,逐个出栈,依次送入S2栈,此时抛弃“(”。
  (5)重复上面的1~4步,直至处理完所有的输入字符。
  (6)若取出的字符是“#”,则将S1栈内所有运算符(不包括“#”),逐个出栈,依次送入S2栈。
  完成以上步骤,S2栈便为逆波兰式输出结果。不过S2应做一下逆序处理。便可以按照逆波兰式的计算方法计算了!

4.双栈算符优先级法

  这是计算表达式的第二种方法
  求值的处理过程是自左至右扫描表达式的每一个字符:
  1、当扫描到的是运算数,则将其压入栈OPND,
  2、当扫描到的是运算符时:
    如这个运算符比OP栈顶运算符的优先级高,则入栈;
    如这个运算符比OP栈顶运算符优先级低,则从OPND栈中弹出两个运算符,从栈
  OP中弹出栈顶运算符进行运算,并将运算结果压入栈OPND。
  3、继续处理当前字符,直到遇到结束符为止。

5.用二叉树来求解后缀表达式的值

  这是计算表达式的第三种方法

5.1二叉树

基本释义:
  二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个结点最多只能有两棵子树,且有左右之分。
  二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个结点。
  二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。
基本形态:
  二叉树是递归定义的,其结点有左右子树之分,逻辑上二叉树有五种基本形态:
    1、空二叉树——如图(a);
    2、只有一个根结点的二叉树——如图(b);
    3、只有左子树——如图(c);
    4、只有右子树——如图(d);
    5、完全二叉树——如图(e)。
       二叉树五种形态
              图 二叉树的五种形态

5.2实现算法

二叉树求解后缀表达式
二叉树求解后缀表达式

四、参考资料

【1】百度百科 前缀表达式 https://baike.baidu.com/item/%E5%89%8D%E7%BC%80%E8%A1%A8%E8%BE%BE%E5%BC%8F
【2】百度百科 中缀表达式https://baike.baidu.com/item/%E4%B8%AD%E7%BC%80%E8%A1%A8%E8%BE%BE%E5%BC%8F
【3】百度百科 后缀表达式
https://baike.baidu.com/item/%E9%80%86%E6%B3%A2%E5%85%B0%E5%BC%8F?fromtitle=%E5%90%8E%E7%BC%80%E8%A1%A8%E8%BE%BE%E5%BC%8F&fromid=6160580
【4】百度百科 栈
https://baike.baidu.com/item/栈/12808149?fr=aladdin
【4】百度百科 二叉树
https://baike.baidu.com/item/二叉树
【5】课程ppt 计算机软件技术实习技术提示
【6】图解后缀表达式的计算过程 https://www.cnblogs.com/jiu0821/p/6692878.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值