nyoj 35-表达式求值(stack, 栈的应用)

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 }

猜你喜欢

转载自www.cnblogs.com/GetcharZp/p/9070083.html