由于其 RPN,操作可以建模为堆栈的一系列转换。在堆栈上加载一个输入部分,然后按顺序执行您的操作就可以了。不需要树,它隐含在操作顺序中。也不需要重新解析,它确实是一系列操作(函数或函子),而不是表示操作的符号序列。
我会选择仿函数,因为我更喜欢存储对象的引用或指针,而不是存储函数的引用或指针。您将其实现为具有重载运算符 () 的类,该运算符执行所需的堆栈转换(例如,如果它是乘法函子,则将两个顶部元素相乘)。
上图:古代设备以这种方式工作......
至于堆栈中存储的内容和未存储的内容:
- 首先,您的操作数存储在与输入顺序匹配的队列中
- 您的运算符对象,解析一次且永不更改的结果,分别存储在运算符队列中。
- 应用“get”运算符会将一个操作数从队列传输到操作数堆栈
因此,例如,如果您想计算
sin (3 + 4) / (5 + 6)
你的操作数队列是:
[start] 3 4 5 6 [end]
您的运算符对象队列(它包含指向函子的指针,而不是符号,每个函子只有一个实例,但可能被多次引用)是:
[start] &getFunctor &getFunctor &addFunctor &sinFunctor &getFunctor &getFunctor &addFunctor ÷Functor [begin]
您的操作数堆栈开始为空:
[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]
您只需继续应用相同的操作员队列,一切都会正常工作。