我正在设计一个程序,该程序将对流数据执行某些操作。操作由运行时提供的RPN(反向抛光表示法)表达式定义。正在从文件源流式传输数据,一次传输一个固定大小的部分。操作引用了数据的当前输入部分,例如data[1]
。该程序将相同的操作应用于所有输入部分(并输出结果)。
实现一个RPN解析器非常容易,该解析器对数字进行运算并进行算术运算以得出结果。但是,使用这种实现方式将意味着为每个数据部分重新解析RPN。
我要实现的是以某种方式构建一个对象,该对象将基于对数据的基本操作的字母来保存曾经解析过的RPN实现,其中程序将提供输入数据(或填写输入),调用该对象的operator()
获取并输出结果。
如何callable expression
使用“非现代” C ++(否C++11
或C++14
)实现这样的类(a )并构造这样的对象?
由于具有RPN,因此可以将操作建模为堆栈的一系列转换。将一个输入部分加载到堆栈上,然后按顺序执行您的操作即可解决问题。不需要树,它按操作顺序是隐式的。无需重新解析,它实际上是一系列操作(函数或函子),而不是一系列表示操作的符号。
我会选择函子,因为我喜欢存储对象的引用或指针要比存储函数的引用或指针更好。您可以将其实现为具有重载的operator()的类,该类执行所需的堆栈转换(例如,如果是乘法函子,则将两个顶部元素相乘)。
上图:以这种方式运行的古老设备...
至于什么存储在堆栈上,什么不是:
因此,例如,如果您想计算
sin (3 + 4) / (5 + 6)
您的操作数队列是:
[start] 3 4 5 6 [end]
您的操作员对象队列(它包含指向函子的指针,而不包含符号,每个函子只有一个实例,但可能被多次引用)是:
[start] &getFunctor &getFunctor &addFunctor &sinFunctor &getFunctor &getFunctor &addFunctor ÷Functor [begin]
您的操作数堆栈开始为emptpy:
[top][bottom]
应用操作员队列将随后为您提供:
(get) [top] 3 [bottom]
(get) [top] 3 4 [bottom]
(add) [top] 7 [bottom]
(sin) [top] 0.657 [bottom]
(get) [top] 5 0.657 [bottom]
(get) [top] 5 6 0.657 [bottom]
(add) [top] 11 0.657[bottom]
(divide) [top] 0.0597 [bottom]
如果您随后想要将完全相同的操作应用于例如
[start]10 20 30 40[end]
只需替换操作数队列(或使操作数队列的起始指针指向操作数文件的下一个“块”,然后针对此新的操作数序列再次运行操作符队列即可。
请注意,如上所述,运算符队列不包含运算符,而是指向立即可用的函数对象的指针,这些对象将在您调用它们后立即执行其操作,而无需重新解析或重新生成代码。
因此,如果您有大量数据:
[start of file]3 4 5 6 10 20 30 40 -1 -10 15 80 ...[end of file]
您只需继续应用相同的操作员队列,一切便会正常进行。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句