【原创】Delphi实现数学表达式的计算(逆波兰式法)-四则运算解析这文主要内容为123 发表于 2011-5-31 00:19:55发表的“逆波兰表达式,北大未名湖站 - 编程技术 - 必度!”帖子 http://www2./forum.php?mod=viewthread&tid=32&page=1 但帖子中的内容很多不够完善,比如左右单目符号、函数名、函数参数逗号等都没有给出处理方式, 我做较大的改进,用Delphi 7做了测试,并公开源代码供大家参考,相互学习! 程序下载地址:ExpCalculator.rar(因为使用了第三方的皮肤美化,360可能会提醒有木马,请大家放心,绝对安全!) (程序里面美化版使用第三方的皮肤AlphaControls v6.65: http://blog.csdn.net/cceevv/article/details/5599735) 源代码下载地址:ExpCalcV2.3.rar 众所周知,计算机处理表达式的难点在于括号的处理,在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,所以,这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法。按此方法,每一运算符都置于其运算对象之后,故称为后缀表示。如a+b表达为ab+。这种后缀表达式非常方便去掉运算符优先级的影响与括号,甚至是单目运算符: 示例说明: 1. a*b+c*(d+e) 逆波兰表达式: ab*cde+*+ 3.a-(-(b-c)) 逆波兰表达式: abc-~ - 预处理: -(负号)处理:用~代替 +(正号)处理:用@代替,或者将其在字符串中删除 数学自然常数 e 与圆周率 pi 的用 (2.718281828459045) 与 (3.1415926535897932384) 代替(包含前后的括弧)
* 读入一个数据(数值与函数名非单个字符,需要做判断处理) 2. 如果是右单目运算符,直接入存储器栈;比如 阶乘!与百分号% 7.如果是函数参数的连接逗号“,”时,则弹出符号栈数据,直到遇到左括弧 ( 或者逗号,为止,再将逗号,入符号栈; 此外还有一些处理的技巧,比如定义一个优先级最低的运算符作为表达式结束的标志(用#标示,添加在表达式结尾处),在符号栈里首先加入一个结束标志,那么表达式读完时则自动弹出栈中所有符号,并写入存储器结尾表示成功。 1、首先是从左至右扫描数据段,如果读出的是数据则压入计算中间值存储栈; 2、遇到单目运算符号就从计算中间值存储栈弹出一个数据进行运算,再把结果压回计算中间值存储栈; 3、遇到双目运算符号就从计算中间值存储栈弹出两个数据进行运算,再把结果压回计算中间值存储栈;这里需要注意减法与除法的计算顺序是第一次弹出的值作为减数和除数,第二次弹出的值作为被减数和被除数。 4、遇到逗号,就从计算中间值存储栈弹出两个数据用“,”连接起来直接将数值字符串压入计算中间值存储栈,不做计算。比如 12 13 ,压入13,12 5、遇到函数,弹出计算中间值存储栈的相关数据调用函数进行计算; 这样,返回结果就是栈中唯一的数据,我们完成了逆波兰表达式的全部计算过程。 最后还有一点就是检查给点表达式是否正确,就是下面的 function CheckCalcExp(const ExpT: string; var AInfo: string): boolean; 这样保证计算不会出错,具体见代码。 /* 表达式计算 */ 表达式计算器 V2.3 支持以下功能: pdisspace(x1,y1,z1,x2,y2,z2) 空间两点 |
|