仿查询分析器的C#计算器——1.初步分析
计算器是很多编程初学者都做过的,从最简单的控制台程序开始,输入值,输入运算符,再输入值,得到一个结果。带界面的基本上是模仿Windows操作系统的计算器,通过按钮输入值和运算符,然后给出运算结果。能不能直接输入表达式,或者能够对好几个表达式进行计算,或者选择表达式中的一部分进行计算,如果输入错误能不能指出表达式中的错误位置?这样的要求类似于MS SQL的查询分析器,本系列文章将介绍如何实现这样一个计算器。(这些内容已经涉及到编译原理,但本人并非计算机专业毕业,只是稍微看了一下编译原理的资料,专业词汇比如有限状态机之类就不提了,咱也不是很pro,呵呵。)
首先给出一个表达式5*3+12/4,我们拿到这个表达式之后会得到如下分析:
1.乘法的优先级高后面的加法,先算乘法,乘号两边的数分别是5和3,执行乘法5*3=15
2.加法的优先级没有后面的除法优先级高,先算除法,除号两边的数是12和4,执行除法12/4=3
3.乘除法做完之后再做加法,这时候加法并不需要知道两边到底怎么计算的,只需要知道两边计算后的值就可以了,乘法的值是15,除法的值是3,执行加法15+3=18
在这个表达式后面再加一个步骤:5*3+12/4-8,这时候只不过多了一步操作
4.做完加法后做减法,减号也不需要知道两边怎么计算的,向两边请求值,得到加法的值是18,另一边是一个数字8,不需要计算就直接给它,执行减法18-8=10
再稍微改变一下:5*3+12/4-8/2,计算过程就是
4.做完加法准备做减法,但后面的除法优先级高,先做除法,除号两边的数是8和2,执行除法得到4
5.然后执行减法,减法左边是执行加法后的值18,右边是执行除法后的值4,执行减法18-4=14
到此会发现,其实可以把每一个操作符理解成一个数值存储单元,并且该单元可以根据它两边的数值进行一定的计算得到自身的值。它只关心两边的值,而不需要关心值是通过什么算法得来的。这样就有了二叉树的味道,一个结点下面可以有两个子结点。因此,不管表达式多复杂,最终都只有一个结果,这个结果就是最后一个操作符对它两边的值进行计算得到的,而最后一个操作符就可以理解成根节点。下面,就把表达式按照树的形状分解:
这里减法就是根节点,它向下请求值并进行计算。它的下级也是采用同样的方法向下请求值,请求到值后就执行自身的计算,把计算结果存储在自己的存储单元里,然后让上一级调用自身的值。最后由根节点计算其下级的值得到整个表达式的值。最终计算完的树结构如下:
我在实际编程中就是采用这种方法对表达式进行分析和计算的,如图:
输入界面(选择部分表达式计算)
至于如何将表达式分析成树形结构,以及如何调用下级节点求值,在以后的文章中详细介绍。
代码下载:https://files.cnblogs.com/conexpress/ConExpress_MyCalculator.rar
(本程序还有一些细节上的bug,有兴趣的朋友可以完善一下。)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?