藍橋杯 演算法訓練 表示式計算

2021-08-06 06:37:35 字數 2906 閱讀 3048

之前在學習棧的時候老師講過這個問題

思路就

1.將表示式(中綴式)轉化成字尾式;

2.進行字尾式的計算。

思路看起來很簡單,但是實際在敲**的時候還是要注意很多問題。下面分享一下個人做法,可以改進之處還希望大家可以指出來,共同進步!

一:將中綴式轉化為字尾式

個人採用的是邊輸入邊進行處理:首先設定兩個棧,乙個是字尾式棧,乙個是符號棧。如果是數字,直接放入到字尾式棧中;如果是符號:

(1)比較算符優先順序,如果符號棧的棧頂符號比將要進棧的符號優先順序高,那麼將符號棧的棧頂元素彈出,進入到字尾式棧中,接著進行棧頂元素和待進棧元素的比較,直到棧頂元素優先順序比待進棧符號優先順序低。如果符號棧的棧頂符號優先順序低,則將將要進棧的符號壓入到符號棧中,稱為新的棧頂元素。以上涉及到了:算符優先順序的比較,實現**如下:

紫框詳解:我們知道,『(』的優先順序是最高的,那麼如果它作為棧頂元素與其他符號比較之後,會被彈出到字尾式棧。然而我們字尾式棧不希望有括號的出現,而符號棧希望括號可以保留,因為我們需要找到後面的『)』與左括號進行配對。所以這裡需要約定,如果棧頂元素是左括號,那麼下乙個符號直接進棧不進行比較。

以上是我們字尾式轉化的**。在suffix函式**化成字尾式)中,我們是邊輸入邊處理,如果是數字,直接進棧,呼叫isnum函式;如果是符號,呼叫issymbol函式。

在issymbol函式中,我們做的不僅僅是優先順序的判斷,因為有括號這個特殊的符號存在,所以我們需要給予特殊考慮。在遇到右括號的時候,我們應該將符號棧中的元素彈出,直到遇到左括號,但是左括號不彈入到字尾式棧中。

如果不是右括號,我們就判斷優先順序,但是在這之前,還需要做的一步就是設定分界符,我們這裡使用的是'#'號。為什麼設定分界符呢?我們知道,讀入表示式的時候使用的是char型,乙個乙個讀的,這樣產生的問題是,如果數字是10以內的,沒有影響,但是如果大於等於10,則會分成多部分讀入,例如23讀進來是2,3,在不同的陣列單元中,那麼運算元字的時候就不知道到底是一位數還是兩位數,所以我們需要『#』號,字尾式的形式就成了:1#23#4#+......這樣子的,很容易區分運算元是幾位。

我第一次做的時候,忽略了乙個問題:就是將符號棧的剩餘元素全部壓入到字尾式棧中。因為在優先順序比較之後,很多符號可能因為在操作順序中靠後,所以並沒有進入到字尾式中,因此千萬不能忘了他們的存在。

到這裡,我們的字尾式轉換就完成了。工程相當於完成了一半,接下來就應該是字尾式的計算:

前面說到過了,我們字尾式中通過'#'號對數字進行了區分,那麼我們進行計算的時候,先要把運算元準確的計算出來,放入到數字棧(num)中。

紅框詳解:對於轉之後的字尾式,計算運算元我想到的辦法是設定乙個first和last指標,在first和last之間的是乙個運算元,那麼區分的標誌就是,兩個運算元之間一定有若干個符號。

大家再對照著**,應該可以理解(可能這裡我的方法比較麻煩,希望大家可以指點一二)

下面我們就開始進行計算了:

這裡還是比較簡單的,遇到數字就呼叫cul_num函式,進行數字的計算,遇到符號就進行符號運算。這裡需要注意的就是我們first和last的設定。此外,還應該考慮一下特殊的情況,我當時出現的乙個問題就是:

例如:1#2#3-#4...進行到『-』減號的時候程式就崩掉了,後來想想明白了問題所在,當last指向減號的時候,執行減法功能,然後i++,那麼這個時候,指向的是字尾式棧中的『#『號,而在calculate函式中,沒有對#的相關處理,所以程式崩了。分析得到:我們並不需要#,所以再i++,指向字尾式棧中的下乙個元素。這就是我上面**注釋的「忽略了」這裡的含義。

(本人第一次寫部落格,不到之處還希望大家批評指正,我會繼續努力!共勉!)

藍橋杯 演算法訓練 表示式計算 (python實現)

class stack object 初始化棧為空列表 def init self self.items 判斷棧是否為空,返回 true 或 false defis empty self return self.items 壓棧,新增新元素進棧 defpush self,item 出棧,刪除棧頂元素...

藍橋杯 演算法訓練 字首表示式

演算法訓練 字首表示式 時間限制 1.0s 記憶體限制 512.0mb 提交此題 問題描述 編寫乙個程式,以字串方式輸入乙個字首表示式,然後計算它的值。輸入格式為 運算子 物件1 物件2 其中,運算子為 加法 減法 乘法 或 除法 運算物件為不超過10的整數,它們之間用乙個空格隔開。要求 對於加 減...

藍橋杯 演算法訓練 表示式計算 棧的應用

輸入乙個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。輸入一行,包含乙個表示式。輸出這個表示式的值。1 2 3 4 5 4 表示式長度不超過100,表示式運算合法且運算過程都在int內進行。兩個棧,乙個存數字,乙個存運算子,掃瞄字串,當當前運算子優先順序小於棧頂運算子時,對上一次存...