2009-11-27 20 views
1

我已经编写了一个PHP解析器,它根据来自earlier question的反馈将等式的字符串表示形式转换为RPN。在对它进行测试时,我发现了两个不同的方程,它们解析了RPN中的同一个东西。因为当你解决它们时,它们会在RPN中成为同样的东西,你会得到同样的答案。解析到RPN两个方程给出了相同的表示法,但有不同的答案

  1. 3 + 4 * 8 /(1 -5)
  2. 3 + 4 * 8/1-5

两个最终成为348 * 15 -/+解决时给出了一个这答案-5这是正确的第一个,但第二个答案应该是30.

所以我误解了如何转换为RPN?解析器的代码可以在前面问题的上面链接中找到。

+1

是的,你的解析器坏了。为了帮助你调试:第二个RPN的正确表示是:348 * 1/+ 5-。 – Heinzi 2009-11-27 12:44:22

+0

您是否以正确的方式设置了操作员的优先顺序? – erenon 2009-11-27 12:47:32

回答

1

我在解析器中发现错误。在您的最后一个大else块,你需要

while(!empty($stack) && end($stack) != '(' && $operators[$tokens[$i]] >= $operators[end($stack)]) { 
    $rpn .= array_pop($stack); 
} 
$stack[] = $tokens[$i]; 

更换

$current = end($stack); 
if($operators[$tokens[$i]] == $operators[$current]) { 
    $rpn .= array_pop($stack); 
    $stack[] = $tokens[$i]; 
} else { 
    $stack[] = $tokens[$i]; 
} 

这种变化之后,你的两个测试用例很好地工作在这里。 (我使用了this reference来修复你的代码,我在你的问题中解决了问题后停止了检查你的代码,所以可能会有更多的bug - 我没有证明 - 读过所有东西!)

编辑:重要的是用“> =”替换“==”。如果您始终只有两级优先级,则用循环替换if并非绝对必要。

+0

查看你的链接后,我看到了我的错误,我以为你只弹出堆栈中的最后一个操作符,没有意识到你保持弹出操作符,直到下一个优先级更低。 – RMcLeod 2009-11-27 13:33:57

+0

然而,这并不是破坏你的例子的事情:重要的区别是你只用*相同*优先级(==)弹出ops,尽管你需要弹出*相同的优先级和更高的*(> =)。 – Heinzi 2009-11-27 13:37:32

相关问题