NYOJ 35 表达式求值(逆波兰式求值)

http://acm.nyist.net/JudgeOnline/problemset.php?typeid=4

NYOJ 35 表达式求值(逆波兰式求值)

逆波兰式式也称后缀表达式。

一般的表达式求值式子都为中缀表达式,而后缀表达式求值相对更容易,所以可以将中缀表达式转换为后缀表达式。

 

ps:不了解中缀表达式,后缀表达式的建议先去了解一下。

对于初学者容易弄混这三种,其实前,中,后即节点位置。

前缀表达式树,遍历顺序(节点,左,右)。

中缀表达式树,遍历顺序(左,节点,右)。

后缀表达式树,遍历顺序(左,右,节点)。

 

步骤:

第一步:将中缀表达式转换为后缀表达式。

          1,将+,-,*,/,(等要用到的运算进行优先级处理。

          2,需要用到一个符号栈处理:

              a,数字字符,小数点直接存入另一个字符串S。

              b,’(‘直接入栈,当表达式str字符中‘)’出现,将所有栈顶运算符转移至S直至遇到‘(’,‘(’出栈。

              c,当表达式str字符中的运算符优先级大于等于(注意一定要大于等于)栈顶运算符优先级时,将字符依次存入S,直至小于为止。当前运算符入栈。

              d,最后当str访问完,将栈中剩余运算符存到S。

第二步:将转换后的后缀表达式进行求值。

          1,需要一个浮点型栈(具体根据题目要求)存放数值。

          2,遍历S遇见操作数,小数点时处理后入栈,直至遇见运算符,出栈两个操作数,处理后将结果再入栈。

          3,栈顶元素即为表达式解。

主要注意:

1.小数点的处理。

2,细心。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <stack>
  5 using namespace std;
  6 const int maxn=1000+5;
  7 
  8 string s1,s2;
  9 stack<char> s;
 10 stack<double> c;
 11 
 12 void init()
 13 {
 14     while(!s.empty())
 15         s.pop();
 16     while(!c.empty())
 17         c.pop();
 18 }
 19 
 20 int pro(char ch)
 21 {
 22     switch(ch)
 23     {
 24         case '+':
 25         case '-':return 1;
 26         case '*':
 27         case '/':return 2;
 28         default :return 0;
 29     }
 30 }
 31 
 32 void deal()
 33 {
 34     init();
 35     int i=0,len=s1.length();
 36     s.push('#');
 37     while(i<len-1)
 38     {
 39         if(s1[i]=='(')
 40             s.push(s1[i++]);
 41         else if(s1[i]==')')
 42         {
 43             while(s.top()!='(')
 44             {
 45                 s2+=s.top();
 46                 s2+=' ';
 47                 s.pop();
 48             }
 49             s.pop();
 50             i++;
 51         }
 52         else if(s1[i]=='+'||s1[i]=='-'||s1[i]=='*'||s1[i]=='/')
 53         {
 54             while(pro(s.top())>=pro(s1[i]))
 55             {
 56                 s2+=s.top();
 57                 s2+=' ';
 58                 s.pop();
 59             }
 60             s.push(s1[i]);
 61             i++;
 62         }
 63         else 
 64         {
 65             while(s1[i]<='9'&&s1[i]>='0'||s1[i]=='.')
 66                 s2+=s1[i++];
 67             s2+=' ';
 68         }
 69     }
 70     while(s.top()!='#')
 71     {
 72         s2+=s.top();
 73         s.pop();
 74         s2+=' ';
 75     }
 76 }
 77 
 78 double countt()
 79 {
 80 
 81     int len=s2.length(),i=0;
 82     double y,x;
 83     while(i<len)
 84     {
 85         if(s2[i]==' ')
 86             i++;
 87         else 
 88         {
 89             switch(s2[i])
 90             {
 91                 case '+':x=c.top();c.pop();x+=c.top();c.pop();i++;break;
 92                 case '-':x=c.top();c.pop();x=c.top()-x;c.pop();i++;break;
 93                 case '*':x=c.top();c.pop();x*=c.top();c.pop();i++;break;
 94                 case '/':x=c.top();c.pop();x=c.top()/x;c.pop();i++;break;
 95                 default :
 96                 {
 97                     x=0.0;
 98                     while(s2[i]<='9'&&s2[i]>='0')
 99                         x=x*10+(s2[i++]-'0');
100                     if(s2[i]=='.')
101                     {
102                         i++;
103                         double k=10.0;y=0.0;
104                         while(s2[i]<='9'&&s2[i]>='0')
105                         {
106                             y+=(s2[i++]-'0')/k;
107                             k*=10;
108                         }
109                         x+=y;    
110                     }
111                 }
112             }
113             c.push(x);
114         }
115     }
116     return c.top();
117 }
118 
119 int main()
120 {
121     int t;
122     cin>>t;
123     while(t--)
124     {
125         cin>>s1;
126         s2="";
127         deal();
128         printf("%.2lf\n",countt());
129     }
130     return 0;
131 }
View Code

参考大神博客后,AC了的总结。

不喜勿喷,欢迎赐教,欢迎一起交流

posted @ 2016-05-08 20:40  初见、  阅读(1551)  评论(0)    收藏  举报