2009-11-27 24 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

相關問題