我被要求在C語言中編寫一個簡單的反向波蘭語記法計算器,作爲家庭作業的一部分。我很難理解RPN。你能幫我理解逆波蘭標誌嗎?此外,如何解決這個問題的任何提示將不勝感激。理解逆向波蘭語法,作業作業?
回答
請注意,本例中的代碼是C++。你需要翻譯它才能在C中工作。 – 2010-04-27 16:47:28
Reverse Polish Notation教程就是首先你寫的值寫入表達式的具體方式,則操作要執行。因此,例如,要添加數字3和4,您會寫3 4 +
。
所以寫一個RPN計算器,你需要
- 接受輸入,如從控制檯的一種手段
- 的tokenizing輸入(A裝置,你在做什麼,上破空白是可能就足夠了)
- 甲stack用於存儲的值(操作數)(如圖3和4在上述)
- 操作的字典
然後循環將成爲在本質:
while (there's a token available) {
token = get_the_token
if (token is known operator) {
get the number of values from stack this operation requires (usually two); fail if stack doesn't have enough
perform operation on values
push result on the stack
}
else if (token is valid value) {
push it on the stack
}
else {
show error: invalid input
}
}
show result remaining on stack
你可以看到爲什麼RPN使得編寫一個calcuator相當簡單:你不必擔心有他們所操作的值之間的運營商,而你不知道不需要使用小括號來進行分組,因爲您可以使用更常用的記號形式infix。例如,我們在中間記號中寫(10 + (4 * 2))/9
,我們會在RPN中編寫10 4 2 * + 9 /
。計算器會處理這樣的標記:
10
:這是一個值,將其推到堆棧4
:這是一個值,將其推到堆棧2
:這是一個值,推它在堆棧上*
:這是一個操作符,彈出窗口2和4離開堆棧並將它們相乘(4 * 2
);將結果(8)推送到堆棧上+
:這是一個操作符,彈出8和10堆棧並添加它們(10 + 8
);堆棧9
上推的結果(18):這是一個值,將其推到堆棧/
:這是一個操作符,彈出9和18從堆棧中和將它們劃分(18/9
);在堆棧上推的結果(2)(注意,在堆疊 — 9的頂部的值,在這種情況下 —是除數,在它之下 —的下一個值是被除數)- 輸入的結束,在堆棧上顯示的值(或多個):
2
不錯。什麼,爲什麼和如何在一個簡潔的包裝。 – dmckee 2010-04-27 23:00:11
Reverse Polish Notation是表示法,其中運營商按照操作數的數學表達式的形式。在評估RPN表達式時,每個二元運算符引用緊接在其之前之前的兩個操作數。藉此RPN表達,例如:
5 4 3 + *
開始從左側的掃描表達,直到你來到第一家運營商,這是+
。該運算符的操作數爲4
和3
(緊接它之前的那些),所以我們可以用結果7
替換全部三個。 (請注意,括號不是必需的,但我正在使用它們來幫助澄清含義)。
5 (4 3 +) * => 5 7 *
現在我們有運營商*
,和兩個操作數5
和7
(這是真正的4 + 3的結果)。我們乘以5
和7
,整個表達式評估爲35
。
5 7 * => 35
這是評估任何RPN表達式的通用算法。
RPN表達式是特別適合用於通過使用被稱爲stack的數據結構的計算機計算結果爲。
堆棧是一個有序集合,其中一端指定爲「頂部」。項目總是添加到堆棧或從頂部的堆棧中移除。這樣,唯一要移除的項目始終是最近添加的項目。由於這個原因,堆棧有時被稱爲Last In First Out(或LIFO),因爲推入堆棧的最後一個元素位於頂部,因此將首先被刪除。
在C中,您可以實現一個包含兩個變量的堆棧:一個數組(足夠容納期望堆棧需要的最大數量的元素)以及一個指示數組中當前哪個索引位於頂部的整數。
堆棧非常適合評估RPN表達式,因爲當遇到運算符時,它總是適用於最近遇到的操作數。因此,當您從左側掃描表達式時,可以將操作數保存在堆棧中。再以我們的例子:
5 4 3 + *
這裏的第一件事情是一個操作數(5
),所以將其推送到堆棧(其初始爲空)。然後我們遇到4
並將它推入堆棧。它成爲新的頂部。然後我們與3
一樣。
5 4 3 <-- top
+ * // Remaining expression
接下來我們遇到了+
運算符。我們知道它適用於以前遇到的操作數,但我們在哪裏可以找到它們?當然,在堆棧頂部!從堆棧彈出3
和4
,並添加它們以獲得7
。但是如何處理結果呢?那麼,它可能是操作數另算,所以將其推回棧上(就像我們更換了操作數和運算符的結果,當我們評估用手錶達):
5 7 <-- top
* // Remaining expression
現在我們看到*
。再一次,最近遇到的操作數是堆棧中的兩個最高操作數。我們彈出它們並乘法得到35
,然後將它推回棧上。
35 <-- top
// No expression remaining
在這一點上,我們已經達到了表達式的結束和堆棧上的唯一的事情就是結果。我們完成了!您可以看到操作數堆棧如何「保存」遇到的第一個操作數,直到遇到相應的操作符(可能位於表達式的另一端)。
如果我們想走到了盡頭,發現還剩下的堆棧多個號碼,會告訴我們,有在表達操作數過多而沒有足夠的運營商。另一方面,如果我們在某個時間遇到了一個操作符,並且在堆棧中的操作數少於兩個,我們就會知道該表達式中操作符太多且操作數不足。
你可以在http://expressionoasis.vedantatree.com/找到一個簡單的實現
- 1. 逆向波蘭語表示法疑難解答C
- 2. 轉換逆向波蘭表示法
- 3. Codechef:反向波蘭語Notation
- 4. 逆波蘭表示法的CFG
- 5. urlencode波蘭語字母不工作
- 6. 處理Cron作業
- 7. 如何解決與多個操作員反向波蘭符號?
- 8. Java批處理作業偵聽器在作業獲得作業ID後
- 9. 斐波納契家庭作業 - java
- 10. J2ME波蘭語 - JSON
- 11. Quartz Jobs的Cron作業語法
- 12. 改變表格語法作業
- 13. 作業類型的語法問題
- 14. 雙語CodeIgniter cron作業
- 15. Java的RPN(逆波蘭式)綴與postfix
- 16. 綴以後綴/逆波蘭式
- 17. 逆波蘭式 - 監測輸入
- 18. 瞭解Eclipse作業系列
- 19. 公平的作業處理算法
- 20. 處理「死亡」Java作業的方法?
- 21. linux web作業管理
- 22. SQL Server代理作業
- 23. SQL作業的理由193
- 24. 調度QGIS處理作業
- 25. Rails後臺作業處理
- 26. SQL代理作業歷史
- 27. WP作業管理器 - 作業類型 - 元鍵值
- 28. PHP:運行預定作業(cron作業)
- 29. rsync與cron作業,作業堆疊?
- 30. 卡在Java編程作業作業
重新引導註釋並重新打開問題。感謝那些爲了清晰和內容而編輯的人。 – 2010-04-27 16:26:27
@Daniel:你在那個問題上寫的與OP問的內容沒有任何關係。至於RPN,這個網站已經有足夠的解釋。 – SilentGhost 2010-04-27 16:28:34
你RPN明白你的程序寫序列 – 2010-04-27 16:40:36