简单的可扩展 RPN 计算器类






3.64/5 (8投票s)
2003 年 10 月 20 日
3分钟阅读

51027

1547
本文介绍一个简单但易于扩展的类,该类允许执行算术计算。
引言
本文介绍一个简单但可扩展的 C++ 类,用于执行算术计算。当您需要计算编译时未知的表达式时,可以使用它。我猜它的主要用途是用于计算器程序,然后 - 无论您认为它有什么用处。
这些计算基于一百年前发明的逆波兰表示法技术 - 这是最容易实现的。您可以在 http://www.calculator.org/rpn.html 找到更多关于 RPN 的信息
如何使用
要使用该类,您只需在您的项目中包含一个“calctypes.h”,并在您想要它的地方创建一个该类的对象。 演示项目是用 WTL 7.0 编写的,并且源代码依赖于 WTL 的 CString
(位于“atlmisc.h”中),这通常来说是一个严重的缺陷。您可以看看是否可以轻松地将其替换为 MFC CString
,或者可能只是一个 char*
。
然后,当您需要计算某些内容时,只需调用 Calculate(LPSTR, LPSTR)
函数,其中表达式作为第一个参数,变量列表作为第二个参数。 它将返回计算出的值。
expression
应该只包含数字、运算符和变量(我认为是除了前两者之外的所有内容)。 数字由 '0' 到 '9' 和一个 '.' 组成,运算符标签在“calctypes.h”中配置。 您应该自己尝试一下,我总是使用“x”和“y”等名称作为变量。 例如 "Sin(x+y-Pow(2 +Cos(x-y),x*y))"。 请注意,我将括号视为运算符。
variablelist
是以分号分隔的等式列表,例如 "x=12;y=31;z=2.3323",并且不应有尾随分号。
如何扩展它
“calctypes.cpp”中只定义了数量有限的简单运算符,您可能想添加一些符合您口味的东西。 我在编写这个类的所有努力都是为了使实现新的运算符变得容易。 您可以使用此类创建像“Indicator”或“Magnitude”或“Gradient”之类的运算符。 通过对类进行稍微修改,您甚至可以实现不同的运算符集,这些运算符可以在计算表达式时使用。 限制是所有运算符的参数都不应超过 3 个。 如果有人知道一种先进的技术可以用来在我的类中实现“n”个参数运算符,请告诉我。
现在直接切入正题。计算表达式的代码不以任何方式依赖于定义的运算符。 您应该执行以下操作以将新的算术运算符添加到计算器类
步骤
- 定义一个函数,该函数接受 3 个指向双精度数的指针并返回一个双精度数。
它应该符合以下
typedef
typedef double (*TThreeArgFnPtr) (double * in_pdArg1, double* in_pdArg2 = NULL,double* in_pdArg3 = NULL);
您应该将其放在“calctypes.cpp”文件中,它应该看起来像这样
double Addition(double * in_pdArg1,double* in_pdArg2 = NULL, double* in_pdDummy = NULL) { return *in_pdArg1 + *in_pdArg2; }
- 然后,为您新添加的运算符创建一个结构体
SOperator
的全局对象。该结构的构造函数接受 4 个参数 - 第一个是运算符标签,这是一个字符串,用于标识表达式中的运算符,第二个是它的优先级,第三个是运算符参数的数量,最后一个是应该用于计算的函数(您刚刚添加的)。
您最终应该得到类似这样的东西
SOperator AdditionOperator(_T("+"),1,2,Addition);
一旦完成,您需要在运算符数组中放置一个指向新声明的运算符的指针,该数组是
SOperator* g_aUsualOperators[g_constNumberOfOperators] = ...
最后要做的是修改在“calctypes.h”中声明的
g_constNumberOfOperators
变量
你完成了。 我告诉过你这很容易 :) 随意使用它,不要犹豫发送反馈。 甚至是批评。 :)
待办事项
然而,关于它有一些真正糟糕的事情
- 代码有缺陷。 抱歉没有时间润色它。
- 运算符不能接受超过 3 个参数。 有人知道方法吗?
- 运算符集尚未实现。
- 依赖于
CString
。 - 你说什么? :)