1. 程式人生 > >nyoj 35-表達式求值(stack, 棧的應用)

nyoj 35-表達式求值(stack, 棧的應用)

input cep code cal 比較 else submit cst 保留

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, 棧的應用)