1. 程式人生 > >用棧進行表示式求值

用棧進行表示式求值

先簡單地闡述一下運算子的3個規則: ①先乘方、開方,再乘、除,最後才是加、減; ②從左到右運算 ③有括號得先算括號裡的,再算括號外的。 對於字元一個一個地 getchar(),如果這個字元是數字的話,那麼就將其壓入資料棧,如果是運算子那麼就壓入算符棧,但運算算符壓入算符棧前需要經過一定的處理。 不同運算子有不同的運算優先權,所以要按照一定的優先權計算,但又不僅僅是運算子優先權那麼簡單~ 從數學角度,如果掃描到的運算子優先順序  <  棧頂的算符優先順序,那麼毫無疑問得先算棧頂的算符;如果掃描到的運算子優先順序  =   棧頂的算符優先順序呢?因為規則②,要從左到右運算,那麼還是得先算棧頂的算符,所以說, 如果數學角度的 getchar() <= stact.peak(),那麼程式設計角度的就是  getchar() < stact.peak()  。 如果掃描到“(”呢?因為得先算括號裡的,所以它比棧頂的任何算符,+-*/^都要高,所以將"("壓棧; 掃描到"("之後,繼續掃描算符,這時不管掃描到什麼運算子,因為要先算括號裡的再算括號外的,所以+-*/^不管什麼算符都比“(”要高,所以要將掃描到的算符壓棧。 這時,會有同學有疑問,為啥“(”的優先順序一會比誰都高,一會比又比誰都低呢?這個是為了同一個目的——先算括號裡的。那什麼時候比誰都高,什麼時候比誰都低呢?當“(”作為掃描到的算符時,它比誰都高;當作為棧頂的算符時,它比誰都低。 如果掃描到“)”呢?這個時候,可以證明括號裡只剩下最後一步運算,這時把資料棧裡的兩個資料,和演算法棧裡的一個算符,彈出,進行運算,然後壓入資料棧裡。換句話說,“)”低於除“(”外的任何算符。之後算符棧棧頂的符號是“(”,“)”的優先順序和“(”是相等,這時這兩符號都沒啥用,可以扔了,“)”不比壓棧,而棧頂的“(”得彈出扔掉,這就是所謂的  脫括號  。 總結就是(下面的優先順序均是指程式設計優先順序): 1)  若優先順序getchar() > stack.peak(),getchar()入棧
2)若優先順序getchar() = stack.peak(),脫括號並接受下一個字元(只有 右括號 和 左括號 相等這一情況)
3)若優先順序getchar() < stack.peak(),當前棧頂運算子stack.peak()出棧,即執行stack.pop(),運算元棧頂的兩個運算元退棧與操作符一起運算,並將運算結果入運算元棧;(這種情況是數學角度的  優先順序   getchar() <= stack.peak() )
(要區分這些優先順序的特別之處哦~)