我有一个如下表达式。最小值(最大值(平均值(4,2),2,3),总和(1,2))我已经实现了分流码算法,将中缀转换为反向抛光符号。我添加了带有两个参数的函数MAX、MIN和AVG。但假设若我想实现变量实参,那个么我必须知道每个函数在中缀表达式中有多少实参。有人能告诉我,在将中缀转换为rpn时,我如何修改分流码算法,使其包含每个函数的自变量数量?
因此,如果您有log max(1, 2, 3, 4, 5)
,您将执行:
log => push log to stack
max => push max to stack
( => push ( to stack
1 => push 1 to stack
, => pop top of stack to output => pop 1 to output
2 => push 2 to stack
, => pop 2 to output
...
=> end result: 1 2 3 4 5 max log
问题是,你不知道有多少个参数属于max
,有多少个属于log
(对数可能也有可能不把基数作为参数)。
使用维基百科描述,应该可以计算每个函数参数分隔符(逗号):如果有k
函数分隔符,那么就有k + 1
参数,所以可以输出上面的1 2 3 4 5 max_5 log
。在嵌套函数的情况下,要小心使用不同的计数:
max(1, 2, log(3, 4), 5) => 1 2 3 4 log_2 5 max_4
---------
max has 4 arguments after evaluating log_2(3, 4)
max
令牌有一个计数,log
函数有另一个计数。您需要跟踪堆栈中最顶层函数令牌的计数,也需要跟踪堆栈内所有其他函数令牌的数量,因为您最终可能会恢复这些计数。
我终于做到了。当令牌是一个开括号时,我会将其添加到输出队列中。然后,当转换或执行RPN输出时,如果遇到函数调用标记,我会从堆栈中弹出项目,直到遇到一个左括号,然后丢弃它,并将其间的所有内容都视为函数的参数。
可能不是一个巧妙的解决方案,但效果很好:)
一个稍微整洁的解决方案是制作另一个堆栈。在找到一个开放的括号时,推动当前标记定位此堆栈。然后,当找到一个闭括号时,弹出第一个值,并使用当前标记位置之间的差来查找括号之间的参数总数。如果运算符是一个函数,则可以使用该值,或者以其他方式将其丢弃。
我不确定我是否会把左括号推到输出堆栈中。这意味着对于3*(4+5)这样的操作,您将在堆栈中添加括号。相反,我将使用与函数相关的逻辑:当遇到MAX或MIN时,将标记标记(比如…"|")推送到堆栈。现在,当你进行评估时,你可以使用堆栈上的所有项目,直到第一个"|"作为函数的参数。