無論是面試還是考研,資料結構中都會出現一類題型,就是已知中綴表示式求其字首表示式或者字尾表示式。這類題型多遇見幾個,多做幾個掌握以下方法,就沒問題了。
先說乙個比較簡單的,個人還是比較傾向於這種的二叉樹表示法:
表示式a*b:左子樹為表示式a,右子樹為表示式b,可以先求左子樹所表示的表示式的值,再求右子樹所表示的表示式的值,最後二者相乘。注意,所畫出的二叉樹,它的葉子節點為數值,非葉子節點是運算子。畫出二叉樹以後,依次進行前序遍歷和後序遍歷,可以得出字首表示式和字尾表示式。
例如美團曾經出過的乙個筆試題目:
解答:根據題目,我們可以畫出二叉樹,如圖所示:
然後根據後序遍歷,即可得出字尾表示式,前序遍歷即可得出字首表示式~
另外一種辦法是利用棧進行操作,利用棧進行操作的這一種辦法和許多書上不太一樣,這是我在其他大牛的部落格裡學習的,那麼在這裡附上大牛寫的部落格的**:
大牛的**
順帶把大牛總結的內容自己小結一下:
將中綴表示式轉換為字首表示式:
遵循以下步驟:
(1) 初始化兩個棧:運算子棧s1和儲存中間結果的棧s2;
(2) 從右至左掃瞄中綴表示式;
(3) 遇到運算元時,將其壓入s2;
(4) 遇到運算子時,比較其與s1棧頂運算子的優先順序:
(4-1) 如果s1為空,或棧頂運算子為右括號「)」,則直接將此運算子入棧;
(4-2) 否則,若優先順序比棧頂運算子的較高或相等,也將運算子壓入s1;
(4-3) 否則,將s1棧頂的運算子彈出並壓入到s2中,再次轉到(4-1)與s1中新的棧頂運算子相比較;
(5) 遇到括號時:
(5-1) 如果是右括號「)」,則直接壓入s1;
(5-2) 如果是左括號「(」,則依次彈出s1棧頂的運算子,並壓入s2,直到遇到右括號為止,此時將這一對括號丟棄;
(6) 重複步驟(2)至(5),直到表示式的最左邊;
(7) 將s1中剩餘的運算子依次彈出並壓入s2;
(8) 依次彈出s2中的元素並輸出,結果即為中綴表示式對應的字首表示式。
將中綴表示式轉換為字尾表示式:
與轉換為字首表示式相似,遵循以下步驟:
(1) 初始化兩個棧:運算子棧s1和儲存中間結果的棧s2;
(2) 從左至右掃瞄中綴表示式;
(3) 遇到運算元時,將其壓入s2;
(4) 遇到運算子時,比較其與s1棧頂運算子的優先順序:
(4-1) 如果s1為空,或棧頂運算子為左括號「(」,則直接將此運算子入棧;
(4-2) 否則,若優先順序比棧頂運算子的高,也將運算子壓入s1(注意轉換為字首表示式時是優先順序較高或相同,而這裡則不包括相同的情況);
(4-3) 否則,將s1棧頂的運算子彈出並壓入到s2中,再次轉到(4-1)與s1中新的棧頂運算子相比較;
(5) 遇到括號時:
(5-1) 如果是左括號「(」,則直接壓入s1;
(5-2) 如果是右括號「)」,則依次彈出s1棧頂的運算子,並壓入s2,直到遇到左括號為止,此時將這一對括號丟棄;
(6) 重複步驟(2)至(5),直到表示式的最右邊;
(7) 將s1中剩餘的運算子依次彈出並壓入s2;
(8) 依次彈出s2中的元素並輸出,結果的逆序即為中綴表示式對應的字尾表示式**換為字首表示式時不 用逆序)。
綜上所述,對於出現這種已知中綴表示式求字首表示式和字尾表示式的話,優先採用二叉樹,選擇而已,不用花費太長的時間。
不足之處:後期有時間考慮加上**~
中綴轉前字尾表示式
乙個中綴式到其他式子的轉換方法 這裡我給出乙個中綴表示式a b c d e 第一步 按照運算子的優先順序對所有的運算單位加括號,式子變成 a b c d e 第二步 轉換字首與字尾表示式 字首 把運算符號移動到對應的括號前面 則變成 a bc de 把括號去掉 a bc de 字首式子出現 字尾 把...
中綴表示式轉字尾表示式
using system using system.collections.generic using system.text namespace 中綴表示式轉字尾表示式 class convert public void run top break case case while top 1 st...
中綴表示式轉字尾表示式
將乙個普通的中綴表示式轉換為字尾表示式的一般演算法是 首先需要分配2個棧,乙個作為臨時儲存運算子的棧s1 含乙個結束符號 乙個作為輸入字尾表示式的棧s2 空棧 s1棧可先放入優先順序最低的運算子 注意,中綴式應以此最低優先順序的運算子結束。可指定其他字元,不一定非 不可。從中綴式的左端開始取字元,逐...