簡單計算器 棧 映像的經典利用

2021-10-25 14:14:30 字數 3341 閱讀 9902

題目描述

讀入乙個只包含 +, -, *, / 的非負整數計算表示式,計算該表示式的值。

輸入

測試輸入包含若干測試用例,每個測試用例佔一行,每行不超過200個字元,整數和運算子之間用乙個空格分隔。沒有非法表示式。當一行中只有0時輸入結束,相應的結果不要輸出。

輸出

對每個測試用例輸出1行,即該表示式的值,精確到小數點後2位。

樣例輸入

30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92

0

樣例輸出

12178.21

解題思路:給出的是中綴表示式(即就是算數表示式中運算子總是出現在兩個運算元之間),由於電腦無法識別並且計算,所以需要轉換為字尾表示式(即就是運算子放在運算元之後),最後就是計算字尾表示式。

中綴表示式轉字尾表示式

1)設立乙個操作符棧,用來臨時存放操作符;然後設立乙個陣列或者佇列,用來存放字尾表示式;

2)從左往右掃瞄中綴表示式,如果碰到運算元(注意:運算元可能不止 一位,因此需要一位一位讀入然後再合併在一起,具體實現見**),就把運算元加入到字尾表示式;

3)如果碰到操作符op,就與棧的棧頂操作符的優先順序開始比較,執行的步驟為:

若op的優先順序高於棧頂操作符優先順序,將壓入到操作符棧。

若op的優先順序低於或等於棧頂操作符優先順序,則將操作符棧的操作符不斷彈出到字尾表示式中,直到op的優先順序高於棧頂操作符的優先順序,高於之後將該操作符op壓入操作符棧。

4)重複2)到3)操作,直到中綴表示式掃瞄完畢,之後如果操作符棧中仍有元素,則將它們依次彈出到字尾表示式中。

所謂操作符的優先順序即就是它們計算的優先順序,其中乘法=除法》加法=減法。

那麼如何在**中實現 優先順序呢?,那麼可以通過映像map建立操作符和優先順序的對映,具體實現見**。

關於為什麼當op的優先順序高於棧頂時就壓入操作符棧?

其實對於我來說,更好的理解方法就是按照前面的步驟進行逐步的去實現,也可以這樣自己總結:既然乘法或者除法要比加減法的優先順序 高,那肯定要在棧的最高層,進行計算字尾表示式的話也是從左往右計算,只有在棧頂,出來壓入到字尾表示式中時才可以排在最前面。

關於為什麼當op的優先順序小於或者等於的時候不能壓入操作符棧?

按照操作步驟執行就可以理解。

字尾表示式計算

從左往右掃瞄字尾表示式,如果是運算元,就壓入到棧,如果數操作符,就連續彈出兩個運算元(注意:後彈出的是第乙個運算元,先彈出的是蝶兒個運算元)

進行操作符的運算之後得到的結果繼續壓入到棧

執行以上兩個步驟,直到字尾表示式掃瞄完畢,這時棧中只剩下乙個數,就是最終的答案。

舉例來實現以上所有的步驟,以3+2*5為例:

從左往右掃瞄,

第1步:3進入到字尾表示式中

第2步:+進入到操作符棧中(由於操作符棧中沒有元素,所以不需要比較,直接進入即可)

第3步:2進入到字尾表示式中

第4步:開始與操作符棧的棧頂的操作符的優先順序比較,由於棧頂的操作符為+,所以的優先順序要比棧頂操作符優先順序高,直接進入棧,目前操作符棧的元素為+*

第5步:5進入到字尾表示式中

第6步:由於操作符 棧中的元素非空,所以將其全部壓入到字尾表示式中,最後字尾表示式變為325*+

第7步:3入棧

第8步:2入棧

第9步:5入棧

第10步:遇到了操作符*,所以彈出兩個數(先彈出的是第二運算元,後彈出的是第一運算元),得到結果為2*5,繼續將得到的結果壓入到棧

第11步:遇到操作符+,得到結果為3+2乘以5.

**實現

#include

#include

#include

#include

#include

#include

using

namespace std;

struct node

;string str;

//定義乙個字串,作為全域性變數

stack s;

//操作符棧

queue q;

//字尾表示式序列

map<

char

,int

> op;

void

change()

//將中綴表示式轉換為字尾表示式

q.push

(temp)

;//將這個運算元壓入到字尾表示式中

}else

//如果是操作符

temp.op=str[i]

; s.

push

(temp)

;//吧該操作符壓入到操作符棧中

i++;}

}while

(!s.

empty()

)//如果操作符棧中還有操作符,就把它彈出到字尾表示式中

}double

cal(

)//計算字尾表示式

else

//如果是操作符

else

if(cur.op==

'-')

else

if(cur.op==

'*')

else

s.push

(temp);}

}return s.

top(

).num;

//棧頂元素就是字尾表示式的值

}int

main()

}while

(!s.

empty()

)//初始化棧

change()

;//將中綴表示式轉換為字尾表示式

printf

("%.2lf\n"

,cal()

);//計算字尾表示式

}return0;

}

c 利用棧實現簡單計算器

簡單計算器 如下 include using namespace std intprio char ch 運算子優先順序判定 double oper double a,double b,char ch 進行運算 int main else else fh.pop 將左括號彈出棧 continue e...

簡單計算器(棧)

開始複習棧,這個題感覺見得很多,各種各樣的,但是核心思路就是把中綴表示式轉化為字尾表示式,我們老師說這個東西也叫作中序二叉樹轉後序二叉樹。大概實現的方式就是用棧來實現 最開始感覺沒啥思路,因為之前一直都不會這種題 論為什麼我這麼菜,之前沒有好好學過棧,知道了stl中有stack後還是方便很多 第一次...

簡單計算器 STL 棧

讀入乙個只包含 的非負整數計算表示式,計算該表示式的值。input 測試輸入包含若干測試用例,每個測試用例佔一行,每行不超過200個字元,整數和運算子之間用乙個空格分隔。沒有非法表示式。當一行中只有0時輸入結束,相應的結果不要輸出。output 對每個測試用例輸出1行,即該表示式的值,精確到小數點後...