poj2269 Friends

计算表达式。

只有3种运算符:*,+,- ,

*优先级高于后两者,后两者优先级相同。

有两种符号:{},()。

利用递归和堆栈即可解决。

首先遇到左括号开始入栈直到遇到右括号,遇到右括号时对括号内的数进行计算。

考虑到*优先级较高,因此遇到*直接对其左右集合进行运算。

最后得到不含括号和*的表达式,从左往右计算即可。

http://poj.org/problem?id=2269

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 const int maxn = 300;
 5 const int maxc = 30;
 6 char buf[maxn];
 7 int stack[maxn][maxc];
 8 char op[maxn];
 9 int p, k;
10 int vis[maxc];
11 
12 void caculate(){
13     //meeting eol or right paren RETURN
14     if(buf[p] == '' || buf[p] == ')') return;
15     if(buf[p] == '('){
16         int k1 = k;
17         ++p, caculate();
18         //guarantee that all contents in the paren computed
19         //figure out the current result
20         for(int i = k1 + 1; i < k; i++){
21             memset(vis, 0, sizeof vis);
22             int o = op[i] == '+' ? 1 : -1;
23             for(int j = 1; j <= stack[k1][0]; j++) ++vis[stack[k1][j]];
24             for(int j = 1; j <= stack[i][0]; j++) vis[stack[i][j]] += o;
25             stack[k1][0] = 0;
26             for(int j = 0; j < 30; j++) if(vis[j] > 0) stack[k1][++stack[k1][0]] = j;
27         }
28         k = k1 + 1;
29         ++p, caculate();
30     }
31     else if(buf[p] == '{'){
32         ++p;
33         stack[k][0] = 0;
34         for(int i = p; buf[i] != '}'; i++, ++p) stack[k][++stack[k][0]] = buf[i] - 'A';
35         k++;
36         p++;
37         caculate();
38     }else if(buf[p] == '*'){
39         if(buf[p + 1] == '(') ++p, caculate();
40         else if(buf[p + 1] == '{'){
41             ++p;
42             stack[k][0] = 0;
43             for(int i = p; buf[i] != '}'; i++, ++p) stack[k][++stack[k][0]] = buf[i] - 'A';
44             k++;
45             ++p;
46         }
47         //caculate stack[k - 2] * stack[k - 1] to update stack[k - 2]
48         memset(vis, 0, sizeof vis);
49         for(int i = 1; i <= stack[k - 2][0]; i++) ++vis[stack[k - 2][i]];
50         for(int i = 1; i <= stack[k - 1][0]; i++) ++vis[stack[k - 1][i]];
51         stack[k - 2][0] = 0;
52         for(int i = 0; i < 30; i++) if(vis[i] == 2) stack[k - 2][++stack[k - 2][0]] = i;
53         --k;
54         caculate();
55     }else{
56         op[k] = buf[p];
57         ++p;
58         caculate();
59     }
60 }
61 
62 void solve(){
63     k = p = 0;
64     memset(vis, 0, sizeof 0);
65     caculate();
66     for(int i = 1; i < k; i++){
67         memset(vis, 0, sizeof vis);
68         int o = op[i] == '+' ? 1 : -1;
69         for(int j = 1; j <= stack[i - 1][0]; j++) ++vis[stack[i - 1][j]];
70         for(int j = 1; j <= stack[i][0]; j++) vis[stack[i][j]] += o;
71         stack[i][0] = 0;
72         for(int j = 0; j < 30; j++) if(vis[j] > 0) stack[i][++stack[i][0]] = j;
73     }
74     putchar('{');
75     for(int i = 1; i <= stack[k - 1][0]; i++) putchar(stack[k - 1][i] + 'A');
76     putchar('}');
77     putchar('
');
78 }
79 
80 int main(){
81     #ifndef ONLINE_JUDGE
82     freopen("in.txt", "r", stdin);
83     #endif // ONLINE_Judge
84     while(gets(buf) && buf[0] != '')    solve();
85     return 0;
86 }
View Code
原文地址:https://www.cnblogs.com/astoninfer/p/4833931.html