使用C ++或C#时,有没有办法将反向波兰表示法解释为“正常”数学符号?我在一家工程公司工作,所以他们偶尔使用RPN,我们需要一种方法来转换它。有什么建议吗?
答案 0 :(得分:15)
是。想想RPN计算器的工作原理。现在,不是计算值,而是将操作添加到树中。所以,例如,2 3 4 + *
,当你到达+时,然后将(+ 3 4)
放在堆栈上,而不是将7放在堆栈上。类似地,当你到达*(你的堆栈在那个阶段看起来像2 (+ 3 4) *
)时,它变成(* 2 (+ 3 4))
。
这是前缀表示法,然后您必须将其转换为中缀。从左到右遍历树,深度优先。对于每个“内部级别”,如果运算符的优先级较低,则必须将操作放在括号中。在这里,您会说2 * (3 + 4)
,因为+的优先级低于*。
希望这有帮助!
编辑:有一个微妙之处(除了不考虑上面的一元操作):我假设左关联运算符。对于右关联(例如,**
),您会得到2 3 4 ** **
⇒(** 2 (** 3 4))
与2 3 ** 4 **
⇒(** (** 2 3) 4)
的不同结果。
当从树中重构中缀时,两个案例都表明优先级不需要包围,但实际上后一种情况需要括起来((2 ** 3) ** 4
)。因此,对于右关联运算符,左侧分支需要具有更高优先级(而不是更高或相等)以避免包围。
另外,您还需要为-
和/
运算符的右侧分支设置括号。
答案 1 :(得分:4)
Shunting Yard算法用于将Infix(即代数)转换为RPN。这与你想要的相反。
你能举个例子说明你的RPN输入吗?我是资深的HP计算器用户/程序员。我认为你有一个包含所有输入和堆栈的堆栈。运营商。我猜你需要重建表达式树,然后遍历树以生成中缀形式。
答案 2 :(得分:2)
C#没有内置支持解析反向波兰表示法(RPN)。您需要编写自己的解析器,或者在线查找。
有许多教程可以将后缀形式(RPN)转换为中缀(代数方程式)。看看this,也许你会发现它很有用,你可以尝试'反向工程'它将后缀表达式转换成中缀形式,记住一个给定的后缀可以有多个中缀符号。实际上讨论将后缀转换为中缀的实例很少。这是我发现非常有用的两部分条目。它还有一些伪代码:
答案 3 :(得分:1)
如果你能阅读ruby,你会找到一些很好的解决方案here
答案 4 :(得分:0)
一种方法是从dragon book的第二章中获取示例,该示例解释了如何编写解析器以从中缀转换为后缀表示法,并将其反转。
答案 5 :(得分:0)
如果你有一些源文本(字符串/ s),你想要从RPN(后缀表示法)转换为“正常表示法”(中缀),这当然是可能的(并且可能不会太困难)。
RPN是为基于堆栈的机器设计的,因为操作的表示方式(“2 + 3” - >“2 3 +”)符合它在硬件上的实际执行方式(将“2”推入堆栈,将“3”推入堆栈,从堆栈中弹出前两个参数并添加它们,然后再推回到堆栈上。
基本上,您希望通过在“叶子节点”上运行要运行的2个表达式以及随后的“父节点”操作本身来创建RPN之外的语法树。这可能是通过递归查看您的输入字符串来完成的(您可能希望确保子表达式被正确括号化以获得更清晰,如果它们还没有)。
一旦你有了这个语法树,你就可以输入前缀,中缀或后缀表示法,只需要对该树进行预订,后序或有序遍历(同样,如果需要,可以清除输出的括号内容) )。
可以找到更多信息here。
答案 6 :(得分:0)
我刚刚用Java写了一个版本,它是here,而一个是Objective-C,而不是here。
可能的算法:假设您在rpn中有输入的堆栈,因为用户会输入它,例如8,9,*。您从头到尾迭代数组,并始终删除当前元素。您评估的这个元素。如果它是操作数,则将其添加到结果堆栈中。如果是操作符,则为操作数弹出结果堆栈两次(对于二进制操作),并在结果堆栈上写入结果字符串。
使用“ 8,9,+,2,* ”的示例输入,您可以在resultstack 上获得这些值(方括号表示单个元素):< / p>
第1步: [8]
第2步: [8],[9]
第3步: [(8 + 9)]
第4步: [(8 + 9)],[2]
第5步: [(8 + 9)* 2]
当输入堆栈为空时,您已完成并且resultStack的唯一元素是您的结果。 (但请注意,输入可能包含多个条目或没有意义的条目,如前导操作:“+ 2 3 /".)
链接中的实现故意不使用任何自制类型,例如运算符或操作数也不适用于例如复合图案。它只是干净简单,因此可以很容易地理解并移植到任何其他语言。
将其移植到C#很简单。