nyoj 35-表達式求值(stack, 棧的應用)
阿新 • • 發佈:2018-05-22
input cep code cal 比較 else submit cst 保留
比如輸入:“1+2/4=”,程序就輸出1.50(結果保留兩位小數)
35-表達式求值
內存限制:64MB
時間限制:3000ms
Special Judge: No
accepted:37
submit:53
題目描述:
ACM隊的mdd想做一個計算器,但是,他要做的不僅僅是一計算一個A+B的計算器,他想實現隨便輸入一個表達式都能求出它的值的計算器,現在請你幫助他來實現這個計算器吧。比如輸入:“1+2/4=”,程序就輸出1.50(結果保留兩位小數)
輸入描述:
第一行輸入一個整數n,共有n組測試數據(n<10)。 每組測試數據只有一行,是一個長度不超過1000的字符串,表示這個運算式,每個運算式都是以“=”結束。這個表達式裏只包含+-*/與小括號這幾種符號。其中小括號可以嵌套使用。數據保證輸入的操作數中不會出現負數。 數據保證除數不會為0
輸出描述:
每組都輸出該組運算式的運算結果,輸出結果保留兩位小數。
樣例輸入:
2 1.000+2/4= ((1+2)*5+1)/4=
樣例輸出:
1.50 4.00
分析與步驟:
①、類似於表達式求解問題需要用到棧(stack)的思想(即就是先進後出)
②、遇到數字就將數字放入數字棧中
③、遇到字符串就要分開考慮
1、是‘(’就直接入棧,方便遇到‘)‘時,就將‘(‘以後所有的運算棧帶入數字棧運算,結果保存於數字串
2、如果操作棧為空棧直接入棧
3、如果操作棧的棧頂元素優先級小於帶輸入字符的優先級直接入棧
4、其他情況就是要將數字棧與操作棧結合,算出結果保存在數字棧中
5、數字棧中的最後一個元素即為題解
核心代碼(表達式求值模板);
1 int priority(char c) // 表達優先級的大小關系 2 { 3 if (c == ‘*‘ || c == ‘/‘) return 2; 4 if (c == ‘+‘ || c == ‘-‘) return 1; 5 return 0; 6 } 7 8 void cal(stack<char> &my_op, stack<double> &my_num) // 將數字棧與操作棧通過引用的形式實現調用與更改 9 { 10 double b = my_num.top(); 11 my_num.pop();12 double a = my_num.top(); 13 my_num.pop(); 14 switch(my_op.top()) 15 { 16 case ‘+‘: my_num.push(a + b); break; 17 case ‘-‘: my_num.push(a - b); break; 18 case ‘*‘: my_num.push(a * b); break; 19 case ‘/‘: my_num.push(a / b); break; 20 } 21 my_op.pop(); 22 } 23 for(int i = 0; i < len; ++ i) // 判斷是因該執行什麽操作 24 { 25 if(isdigit(s[i])) 26 { 27 double temp = atof(&s[i]); 28 while(isdigit(s[i]) || s[i] == ‘.‘) ++ i; 29 my_num.push(temp); 30 -- i; 31 } 32 else if(s[i] == ‘(‘) 33 { 34 my_op.push(s[i]); 35 } 36 else if(s[i] == ‘)‘) 37 { 38 while(my_op.top() != ‘(‘) 39 cal(my_op, my_num); 40 my_op.pop(); 41 } 42 else if(my_op.empty()) 43 { 44 my_op.push(s[i]); 45 } 46 else if(priority(my_op.top()) < priority(s[i])) 47 { 48 my_op.push(s[i]); 49 } 50 else if(priority(my_op.top()) >= priority(s[i])) 51 { 52 while(!my_op.empty() && priority(my_op.top()) >= priority(s[i])) // 比較的是優先級關系不是ASCⅡ 53 cal(my_op, my_num); 54 my_op.push(s[i]); 55 } 56 }
C/C++代碼實現(AC):
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <stack> 7 #include <map> 8 #include <queue> 9 #include <set> 10 11 using namespace std; 12 const int MAXN = 1010; 13 14 int priority(char c) // 表達優先級的大小關系 15 { 16 if (c == ‘*‘ || c == ‘/‘) return 2; 17 if (c == ‘+‘ || c == ‘-‘) return 1; 18 return 0; 19 } 20 21 void cal(stack<char> &my_op, stack<double> &my_num) // 將數字棧與操作棧通過引用的形式實現調用與更改 22 { 23 double b = my_num.top(); 24 my_num.pop(); 25 double a = my_num.top(); 26 my_num.pop(); 27 switch(my_op.top()) 28 { 29 case ‘+‘: 30 my_num.push(a + b); 31 break; 32 case ‘-‘: 33 my_num.push(a - b); 34 break; 35 case ‘*‘: 36 my_num.push(a * b); 37 break; 38 case ‘/‘: 39 my_num.push(a / b); 40 break; 41 } 42 my_op.pop(); 43 } 44 45 int main() 46 { 47 48 int t; 49 scanf("%d", &t); 50 while(t --) 51 { 52 char s[MAXN]; 53 scanf("%s", s); 54 int len = strlen(s); 55 stack <double> my_num; 56 stack <char> my_op; 57 58 for(int i = 0; i < len; ++ i) 59 { 60 if(isdigit(s[i])) 61 { 62 double temp = atof(&s[i]); 63 while(isdigit(s[i]) || s[i] == ‘.‘) ++ i; 64 my_num.push(temp); 65 -- i; 66 } 67 else if(s[i] == ‘(‘) 68 { 69 my_op.push(s[i]); 70 } 71 else if(s[i] == ‘)‘) 72 { 73 while(my_op.top() != ‘(‘) 74 cal(my_op, my_num); 75 my_op.pop(); 76 } 77 else if(my_op.empty()) 78 { 79 my_op.push(s[i]); 80 } 81 else if(priority(my_op.top()) < priority(s[i])) 82 { 83 my_op.push(s[i]); 84 } 85 else if(priority(my_op.top()) >= priority(s[i])) 86 { 87 while(!my_op.empty() && priority(my_op.top()) >= priority(s[i])) // 比較的是優先級關系不是ASCⅡ,my_op.top()忘記放在priority中,弄的找了半天的bug,::>_<:: 88 cal(my_op, my_num); 89 my_op.push(s[i]); 90 } 91 } 92 my_op.pop(); 93 printf("%.2lf\n", my_num.top()); 94 my_num.pop(); 95 } 96 return 0; 97 }
nyoj 35-表達式求值(stack, 棧的應用)