2019独角兽企业重金招聘Python工程师标准>>>

=======================================

计算器 abacus 的下载地址:http://www.oschina.net/code/snippet_736932_13725

如果你有关于 abacus 的问题或者建议,请发邮件至 zhoucosin@163.com。谢谢。

=======================================

本节介绍一些问题以及如何设计计算器以解决这些问题。

程序的目标:

  • 支持四则混合运算 ok.
  • 支持数学函数,如三角函数、指对函数、组合数等 ok.
  • 支持符号常量,如圆周率、自然对数的底数等  ok.
  • 支持变量运算(并非符号计算) doing...
  • 支持表达式函数(即含有变量的表达式作为函数) doing...
  • 支持有控制流程的函数 wait for doing.

首先确定程序的使用方式,目前只打算以命令行的方式运行程序,暂不考虑界面的问题,程序启动后,用户逐条输入表达式以计算其值,每计算完一个表达式并显示之后,程序将等待用户输入下一个表达式,直到用户输入"quit" 退出程序。

表达式在本质上就是一个由运算符、运算数、标点符号这些表达式元素组成的序列,所以问题的关键在于解释这些序列的数学意义。

首先需要从字符串形式的表达式中提取各个表达式元素(运算符、运算数、标点符号:主要是括号和逗号),并将这些表达式元素依次保存到一个线性的数据结构中去,这称为词法分析。在词法分析之前,应该进行一些预处理,比如检查括号是否匹配。而在词法分析之后也应有一些后处理,比如对标识符作进一步处理,词法分析器只能识别出标识符,它并不知道一个标识符到底是一个函数的名字还是一个符号常量,需要做相应的更换。

经过词法分析之后,我们就得到了一个由表达式元素所组成的序列了,而表达式元素都是有相应的数学意义的,比如运算符有优先级,需要的运算数个数,以及最重要的计算函数指针这些属性,而运算数最主要的属性就是它所对应的数值了。比如表达式 1-2*(sin(pi/3))^2 在经过词法分析以后将被分割成如下的表达式元素序列:

1  -  2  *  (  sin  (  pi  /  3  )  )  ^  2

其中的各个部件都已经有了数学意义(这需要相应的表达式部件类的实现),比如运算符 * 具有属性: 字符串体:“*”,优先级:2, 所需运算数个数:2, 计算函数指针:(一个完成乘法运算的函数)。而最后的运算数2具有属性:字符串体:“2”,数值:2.

这里有一个非常重要的设计,就是把数学函数当成运算符处理。这样做的理由是,函数运算符跟普通的四则混合运算符都能对给定的若干个实数,计算出一个结果来,这说明它们在本质上是一致的,你可以把加法 2+3 写成函数调用的形式 +(2,3),也可以把函数调用 pow(2,3) 按照二元运算符的惯例放在两个运算数之间: 2 pow 3,想必人们对于 2^3 这样的指数写法习以为常,那么这个 2 pow 3 不也是一脉相承的么?而对于一元函数也是一样,一元运算符负号放在运算符之前,那么 sin(3) 也可以写成 sin 3 的形式。总之,把函数运算符跟普通运算符统一处理,这是 abacus 在设计上的一大特色。

接下来就要调整表达式的结构,传统的数学表达式其实是很不规范的,历史上加减乘除这些二元运算符最早发明,很自然的就把它们放在两个运算符之间了,但同样的形式对于非二元运算符就不适用了。又如,作为一元运算符的负号是放在运算数之前的,而阶乘符号却是放在运算数之后的,而函数运算符却采用了另外一种写法: opt(a1,a2,.....)。由此可见传统的数学表达式虽然对人来说是易于理解的,但却不利于计算机进行处理,在此我们需要用一种统一的观点来看待所有的运算符,即运算符的本质是一个映射,能对给定的若个数(输入)产生一个确定的结果(输出),有了这一点认识,我们就希望用一种统一的形式来刻画表达式。

我们采用“运算符前置”的形式来规范数学表达式的结构,它把任何一个表达式放在一对小括号内部,而小括号内的第一个对象就是运算符,剩余的对象均是参与运算的运算数,例如 2+3 的规范形式为 (+ 2 3),而 sin(pi) 的规范式为 (sin pi),并且表达式可以任意嵌套,比如 5*(2-3) 的规范形式为 (* 5 (- 2 3)),作为一个更复杂的例子,一元二次方程x^2-3x+2=0的求根公式(正根)将表示为 (/ (+ (- (-3)) (sqrt (- ((^ (- 3) 2)) (* (* 4 1) 2)))) (* 2 1)) 。虽然这样的表达式对于人来讲是一种痛苦,但由于其格式的规范性,计算机是乐于处理这样的结构的。

由传统形式向规范式转换的过程我们就称之为语法分析,如果有语法错误,在这个过程中将会被发现。在语法分析之前也应该会有一些预处理,例如在词法分析阶段并不能区分负号与减号,这需要在语法分析之前进行一点“有语法倾向”的检查纠正,然后根据括号的层次提升运算符的优先级。

表达式在经过语法分析之后,就已经被转换为规范式了,这个时候进行计算就相当简单了,只要采用递归的方式,在表达式中查找主运算符(即优先级最低的运算符),然后检查剩余的各个运算对象,如果某个运算对象本身也是一个表达式,即含有子表达式,则先计算子表达式的值,最后计算整个表达式的值。 1-2*(sin(pi/3))^2 的计算过程如下:

转换为规范式:  (- 1 (* 2 (^ (sin (/ pi 3)) 2)))

计算过程:

Step 1:     (- 1 (* 2 (^ (sin (/ pi 3)) 2)))

Step2:     (- 1 (* 2 (^ (sin 1.047197551) 2)))

Step3:     (- 1 (* 2 (^ 0.8660256282 2)))

Step4:     (- 1 (* 2 0.7500010327))

Step5:     (- 1 1.500002065)

Step6:     -0.500002065

这样就完成了计算过程。在此处可以看到这个“规范式”带来的一个最大的好处:把语法分析跟递归计算分离开来了,如果不转换成这种规范式而使用传统的数学表达式,那么由于表达式的各种形式(分一元普通运算符,二元普通运算符,函数运算符.....),就只能在语法分析的过程中根据相应的运算符选择合适的形式来进行计算了。而现在引入了这种规范式,在计算过程中根本不用去关心这个运算符是什么类型的运算符。这说明,运算符前置表达式的引进,是 abacus 的另一个非常好的设计。

至此大体设计基本上就完成了。这里有一个用脑图描述的计算器 abacus 的实现,一看就懂的:

http://www.mindomo.com/mindmap/abacus-5b6804e0f3fa466f96bc198c9b5d63d3

zhcosin

2012-10-29

转载于:https://my.oschina.net/zhcosin/blog/86083

计算器 abacus 技术文档之二----初步设计相关推荐

  1. Kooboo CMS技术文档之二:Kooboo CMS的安装步骤

    在IIS上安装Kooboo CMS Kooboo CMS安装之后 安装的常见问题 1. 在IIS上安装Kooboo CMS Kooboo CMS部署到正式环境相当简单,安装过程是一个普通MVC站点在I ...

  2. pythoncad二次开发视频_revit二次开发|bim软件二次开发|revit二次开发教程|Revit二次开发技术文档...

    二次开发 revit二次开发|bim软件二次开发|revit二次开发教程|Revit二次开发技术文档2019-07-08赞( 0 ) 记录一下CAD二次开发的一些简单实例. 1.helloworld ...

  3. (马世龙)Linux下CACTI完全搭建技术文档二

    续(马世龙)Linux下CACTI完全搭建技术文档一 6.完成cacti的安装 1. 首先检查一下rra/下面,有没有数据 2. snmpwalk -v 2c -c public ServerIP i ...

  4. [技术文档] 一劳永逸,用USB设备制作多系统引导

    2019独角兽企业重金招聘Python工程师标准>>> [技术文档] 一劳永逸,用USB设备制作多系统引导  [复制链接] binghe27 艺有所成 当前离线 主题 8  UID ...

  5. 代码统计工具1.1版本技术文档

    代码统计工具1.1版本技术文档 说明:主要记录自己在做这个项目的过程中用到的方法和相关技术 1.首先面临的问题就是怎样选择一个目录,网上搜索了一下,下面是解决方案(用到目录对话框) (1)从默认的磁盘 ...

  6. SLAM学习--视觉slam学习教材推荐(附相关技术文档下载链接)

    (理论上看完前三本,足够掌握视觉slam的所有理论知识,实践部分参考各种开源代码) 一.<视觉slam十四讲>,高翔,清华大学出版社,(目前已出第二版,优先推荐) 以上教材,其实是基于国外 ...

  7. 【资源推荐】良心之作!超过 10000+ 的互联网团队正在使用的在线 API 文档、技术文档工具...

    搞开发的同学都知道一个好的 API 文档是有多重要! 每当接手一个别人开发好的项目,看着那些没有注释的代码,真的头大. 程序员都很希望别人能写技术文档,因为可以提高自己开发的效率,而往往自己却很不希望 ...

  8. 良心之作!超过 10000+ 的互联网团队正在使用的在线 API 文档、技术文档工具

    搞开发的同学都知道一个好的 API 文档是有多重要! 每当接手一个别人开发好的项目,看着那些没有注释的代码,真的头大. 程序员都很希望别人能写技术文档,因为可以提高自己开发的效率,而往往自己却很不希望 ...

  9. 这谁写的技术文档?我想锤死他...

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 后台回复"k8s",可领取k8s资料 很多技术人自己非 ...

最新文章

  1. 2021年图灵奖,花落高性能计算先驱、田纳西大学教授Jack Dongarra
  2. 大学python实训总结-千锋Python实训总结 学好基础才能走的更远
  3. FastAdmin 极速后台管理框架(三周年)V1.0.0.20190410_beta
  4. HDFS的API操作-获取FileSystem方式
  5. 由浅到深理解ROS URDF教程
  6. qchart 怎么点击一下 出一条线_mastercam9.1教程之Mastercam9.1数控编程里面怎么出多个坐标系...
  7. input[type=radio]自定义样式
  8. 递归+分治+贪心+动态规划
  9. 拓端tecdat荣获腾讯云+社区年度最佳作者奖
  10. crt怎么退出编辑模式_securecrt怎么退出当前指令
  11. C语言谭浩强博客,折半查找法--C语言谭浩强版练习6.9
  12. php生成财务科目编码,会计科目代码(2019会计科目代码对照表)
  13. 11.1-4日,RTE2022 第八届实时互联网大会邀您“聚享万象”,线上报名开启
  14. 《基于Python的金融分析与风险管理》学习笔记
  15. Tomcat正常启动却访问不了·解决方法
  16. 用 Mindjet MindManager 管理自己的思维
  17. 机器学习(周志华) 第十四章概率图模型
  18. CSV百字段Oracle建表的身不由己迫不得已解决方案——拼音
  19. python中slice用法
  20. 杂七杂八毒鸡汤(暂停更新)

热门文章

  1. 斯坦福统计学习理论笔记:Percy Liang带你搞定「贼难」的理论基础
  2. 使用R语言分析微信好友
  3. redis系列:通过文章点赞排名案例学习sortedset命令
  4. 日常笔记-css\html篇
  5. CLOUD 04:zookeeper,kafka,hadoop高可用
  6. Oracle Eneterprise Linux 5.8上安装Database 12c
  7. 细数网站成功赢利须具备的四大核心要素
  8. 跟我一起学perl系统管理脚本 第3课
  9. 鸿蒙正式推送时间,鸿蒙系统现已正式推送,更新名单也随之出炉,包括荣耀手机!...
  10. UML博客建模--模块与类图