利用栈进行表达式求解

    以前A掉的表达式求解统统是递归= =,栈一直不知道怎么搞,今天稍微看了看,写了一个较简单的。

    对于一个合法的表达式,只要知道运算符的优先级即可利用栈求解,貌似是将中缀表达式转化为了后缀表达式,这些个名词咳咳= =

    顾名思义后缀表达式就是运算符写在后面嘛,对于a+b就是ab+ ,我们就知道要计算ab的和,对于一些更复杂状态的式子,显然需要一些技巧。

    先来看一道简单的题目    http://acm.nyist.net/JudgeOnline/problem.php?pid=1272  

    注意到这个题目中只有Smax一个函数所以可以用逗号来替代这个函数更加简便,我们用两个栈保存中间变量,一个储存符号的栈sc,一个储存中间值的栈si,还要有一个优先级表。

    当前字符如果是一个数字那就计算出连续的这个数字并加入到si中,如果是个字符的话,与sc栈顶字符比较优先级,如果等于栈顶那就出栈(对于'(',')'这些特殊的匹配符号),如果大于栈顶那么说明应该先执行这个运算符,

入栈即可,如果小于栈顶,说明我们要用掉栈顶的运算符,取出si中的两个数后根据栈顶符号计算后再将结果加入到si中,注意到可能有多个需要计算的运算符所以这里用一个循环表达。为了方便引入'#'这个匹配字符,这样不用判断栈空的情况,显然最后sc中只有一个数字,就是答案了。

  

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<map>
 7 #include<stack>
 8 #include<ctype.h>
 9 using namespace std;
10 #define inf 0x3f3f3f3f
11 char opt[]={'=',',','*','(',')','#'};
12 int g[10][10]={
13 {1,1,-1,-1,1,1},
14 {-1,1,-1,-1,1,1},
15 {1,1,1,-1,1,1},
16 {-1,-1,-1,-1,0,1},
17 {1,1,1,0,1,1},
18 {-1,-1,-1,-1,-1,0}
19 };
20 map<char,int>M;
21 char s[330];
22 stack<char>sc;
23 stack<int>si;
24 int num(int N)
25 {
26     int r=0; while(N){r+=N%10;N/=10;}
27     return r;
28 }
29 int cal(int a,int b,char ch)
30 {
31     switch(ch){
32     case '+':return a+b;break;
33     case '*':return a*b;break;
34     case ',':return max(num(a),num(b));break;
35     }
36 }
37 int main()
38 {
39     int T,N,i,j,k;
40     for(i=0;i<6;++i)
41         M[opt[i]]=i;
42     cin>>T;
43     while(T--){
44         scanf("%s",s);
45         N=strlen(s);
46         s[N]='#';
47         while(!sc.empty())sc.pop();
48         while(!si.empty())si.pop();
49         sc.push('#');
50         for(i=0;i<=N;++i)
51         {
52             int t=-1;
53             if(isdigit(s[i])){
54                 t=s[i]-'0';
55                 while(isdigit(s[i+1])){
56                     t=t*10+s[++i]-'0';
57                 }
58                 si.push(t);
59             }
60             else{bool ok=1;
61             while(ok){
62                 if(s[i]=='S')i+=4;
63                 int x=g[M[sc.top()]][M[s[i]]];
64                 if(x==0) ok=0,sc.pop();
65                 else if(x==-1) ok=0,sc.push(s[i]);
66                 else{
67                     int a1=si.top();si.pop();
68                     int a2=si.top();si.pop();
69                     si.push(cal(a2,a1,sc.top()));
70                     sc.pop();
71                 }
72             }
73         }
74         }
75         cout<<si.top()<<endl;
76     }
77     return 0;
78 }

 

 

http://acm.hdu.edu.cn/showproblem.php?pid=1237

    有了四种运算+-*/ , 其实和上面的类似改下代码就能AC,当然可以写的更简单,不过为了练习栈就这样写了。

   

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<map>
 7 #include<stack>
 8 #include<ctype.h>
 9 using namespace std;
10 #define inf 0x3f3f3f3f
11 char opt[]={'+','-','*','/','(',')','#'};
12 int g[10][10]={
13 {1,1,-1,-1,-1,1,1},
14 {1,1,-1,-1,-1,1,1},
15 {1,1,1,1,-1,1,1},
16 {1,1,1,1,-1,1,1},
17 {-1,-1,-1,-1,-1,0,1},
18 {1,1,1,1,0,1,1},
19 {-1,-1,-1,-1,-1,-1,0}
20 };
21 map<char,int>M;
22 char s[1005];
23 stack<char>sc;
24 stack<double>si;
25 double cal(double a,double b,char ch)
26 {
27     switch(ch){
28     case '+':return a+b;break;
29     case '*':return a*b;break;
30     case '-':return a-b;break;
31     case '/':return a/b;break;
32     }
33 }
34 int main()
35 {
36     int T,N,i,j,k;
37     for(i=0;i<7;++i)
38         M[opt[i]]=i;
39     while(gets(s)){
40         N=strlen(s);
41         if(N==1&&s[0]=='0') break;
42         s[N]='#';
43         while(!sc.empty())sc.pop();
44         while(!si.empty())si.pop();
45         sc.push('#');
46         for(i=0;i<=N;++i)
47         {
48             if(s[i]==' ') continue;
49             double t=-1;
50             if(isdigit(s[i])){
51                 t=s[i]-'0';
52                 while(isdigit(s[i+1])){
53                     t=t*10+s[++i]-'0';
54                 }
55                 si.push(t);
56             }
57             else{bool ok=1;
58             while(ok){
59                 int x=g[M[sc.top()]][M[s[i]]];
60                 if(x==0) ok=0,sc.pop();
61                 else if(x==-1) ok=0,sc.push(s[i]);
62                 else{
63                     double a1=si.top();si.pop();
64                     double a2=si.top();si.pop();
65                     si.push(cal(a2,a1,sc.top()));
66                     sc.pop();
67                 }
68             }
69         }
70         }
71         printf("%.2f\n",si.top());
72     }
73     return 0;
74 }

 

posted @ 2017-09-19 18:07  *zzq  阅读(1538)  评论(0编辑  收藏  举报