女朋友学高数,我花了15分钟用栈给她写了一个计算器

1,039 阅读4分钟

前记

女朋友说:“高数好难,看我最近挺辛苦的,你送我一个礼物给我,让我开心一下吧。你猜猜我想要什么。”

我想了半天,从书到鞋子到电子产品最后到生活用品,感觉什么都不缺,然后和她说:“你说要送啥,我就送啥吧”

她坚持要我猜:“不行,你一定要说一个礼物,并且这个礼物要你亲手做的”

于是,我认真了起来,拿起手机,上淘宝逛了几分钟,但还是没能想出来缺点什么,最后实在没办法了:“这样吧,如果你实在想让我送东西,那我帮你写一个计算器吧”

文章的标题只是噱头,作为热爱交流技术的学习者,我们应该脚踏实地,所以我会保证文章的内容都是干货!

设计原理

根据输入中缀算术表达式,利用栈帧结构,实现转换成后缀表达式输出,再对该后缀表达式求值计算输出结果。最终设计出一个计算器。

适用范围:+ - * / % 整数 小数 负数

设计思想

逻辑设计

  1. 建立两个栈,栈stack和栈Node
  • stack栈用于储存字符数组,以字符形式存储中缀表达式的元素。
  • Node栈用于储存双精度浮点型的数组,用于存储中缀表达式的元素值和各元素运算操作后的值。
  1. 设计以下两个函数和相应的入栈出栈操作。
函数名 参数 作用
Mtf_function() char *p1,char *mid,char *final 用于中缀转后缀
Caculate() stack *M,char *final 计算后缀表达式值

Mtf_function()函数设计

(栈为stack)

(1)如果遇到操作数,直接将其输出。

(2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时将其放入栈中。

(3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。

(4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到" ) "的情况下我们才弹出" ( ",其他情况我们都不会弹出" ( "。

(5)如果读到了输入的末尾,则将栈中所有元素依次弹出。

Caculate()函数设计

(栈为Node栈)

1)遍历表达式,遇到的数字首先放入栈中

2)接着读到运算操作符如“+”,则弹出栈顶元素和下一个元素,执行相应的运算操作,并将计算结果压入到栈中。

3)读到下一个元素,将其直接放入栈中。

4)读到下一个元素如“”,弹出栈顶元素和下一个元素,执行85,执行相应的运算操作,并将计算结果压入到栈中……以此类推。最后求的值存在栈顶上。

对于小数点的处理算法

  1. 原理:先将小数化为整数,然后除以10的相应权重。建立一个循环,令小数的值sum初始化0,10的相应权重j=0,判断小数点后的字符数组元素是否属于0-9,若是,将小数点后移,sum = sum * 10 + 元素所对应的值,10的相应权重j加一,直到下一个元素不属于0-9。
  2. 具体算法如下
    在这里插入图片描述

对于负号的处理

负号的出现位置是字符数组的第一个元素或左括号后面的元素。为避免与减号“-”混淆,通过判断字符数组的第一个元素或左括号后面的元素是否为“-”找出负号,并替换成“M”。中缀转后缀时若元素为“M”则输出“-”。计算后缀的值时若元素为“M”,则之后的元素值(包括小数)转换为相反数后进行操作。

主程序流程图和各模块调用关系

在这里插入图片描述

物理设计

  1. 基于在内存开辟连续存储空间数组实现,C声明定义字符栈帧结构,包含字符数组,用于中缀转后缀表达式

    在这里插入图片描述

  2. 相应的节点的含义

    在这里插入图片描述

  3. 进出栈操作

    在这里插入图片描述

  4. C声明定义整型栈帧结构,包含整型数组,用于计算后缀表达式求值。

    在这里插入图片描述

  5. 相应的节点的含义

    在这里插入图片描述

  6. 进出栈操作

    在这里插入图片描述

测试

  1. 测试用例
    在这里插入图片描述
    在这里插入图片描述
  2. 测试结果
    在这里插入图片描述

源代码(带注释)

代码写的是C语言版,后续有时间会补上java版 github代码链接

如果有收获?希望老铁们来个双连击,给更多的人看到这篇文章

1、老铁们,关注我的原创微信公众号「程序猿的进阶」,主要是IT与竞赛

2、创作不易,顺便点个赞呗,可以让更多的人看到这篇文章,激励一下我这个小白。