1. 程式人生 > 其它 >表示式求值(棧)

表示式求值(棧)

題目描述

給定一個表示式,其中運算子僅包含+,-,*,/(加 減 乘 整除),可能包含括號,請你求出表示式的最終值。

注意:

  • 資料保證給定的表示式合法。
  • 題目保證符號-只作為減號出現,不會作為負號出現,例如,-1+2,(2+2)*(-(1+1)+2)之類表示式均不會出現。
  • 題目保證表示式中所有數字均為正整數。
  • 題目保證表示式在中間計算過程以及結果中,均不超過231−1。
  • 題目中的整除是指向0取整,也就是說對於大於0的結果向下取整,例如5/3=1,對於小於0的結果向上取整,例如5/(1−4)=−1。
  • C++和Java中的整除預設是向零取整;Python中的整除//預設向下取整,因此Python的eval()
    函式中的整除也是向下取整,在本題中不能直接使用。

【輸入格式】

共一行,為給定表示式。

【輸出格式】

共一行,為表示式的結果。

【資料範圍】

表示式的長度不超過105

【輸入樣例】

(2+2)*(1+1)

【輸出樣例】

8

對於一箇中綴表示式,優先順序高的應當被先算,低的則後算,那麼體現在樹上就是運算子優先順序高的表示式樹應當處於越下端。

思路:

  ①從左到右遍歷表示式,遇到數字就把數字壓入數字棧;

  ②遇到運算子,則比較當前運算子與棧頂運算子的優先順序,如果當前運算子的優先順序小於棧頂運算子,則說明棧內運算應當要被計算,彈出數字棧資料與棧頂運算子進行運算,將結果壓入數字棧中;

  ③遇到左括號則直接入運算子棧;

  ④遇到右括號則不斷彈出彈出數字棧資料與棧頂運算子進行運算,將結果壓入數字棧中,直到下一個棧頂運算子為左括號,將其彈出並繼續遍歷表示式。

 1 #include <iostream>
 2 #include <stack>
 3 #include <unordered_map>
 4 #include <string>
 5 using namespace std;
 6 stack<int> num;
 7 stack<char> op;
 8 unordered_map<char
,int> pri = {{'+',1},{'-',1},{'*',2},{'/',2}}; 9 10 void eval() 11 { 12 int b = num.top();num.pop(); 13 int a = num.top();num.pop(); 14 char ope = op.top();op.pop(); 15 if(ope == '+') num.push(a + b); 16 else if(ope == '-') num.push(a - b); 17 else if(ope == '*') num.push(a * b); 18 else num.push(a/b); 19 } 20 21 int main() 22 { 23 string str; 24 cin >> str; 25 for(int i = 0;i < str.size();++i) 26 { 27 char s = str[i]; 28 if(isdigit(s)) 29 { 30 int n = 0,j = i; 31 while(j < str.size() && isdigit(str[j])) 32 { 33 n = n*10 + str[j] - '0'; 34 ++j; 35 } 36 num.push(n); 37 i = j - 1; 38 } 39 else if(s == '(') op.push(s); 40 else if(s == ')') 41 { 42 while(op.top() != '(') 43 eval(); 44 op.pop(); 45 } 46 else 47 { 48 while(op.size() && pri[op.top()] >= pri[s]) 49 eval(); 50 op.push(s); 51 } 52 } 53 while(op.size()) 54 eval(); 55 cout << num.top() << endl; 56 return 0; 57 }