• 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
    ",countt());
    129     }
    130     return 0;
    131 }
    View Code

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

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

  • 相关阅读:
    使用paramiko的问题记录
    python常见异常及解决方法
    linux ps -aux各列含义
    常用技能
    超时程序管理
    跨年的总结和展望
    java json和对象互转
    一些常用功能总结
    ResultSet转成java类对象
    python常用功能总结
  • 原文地址:https://www.cnblogs.com/yang-/p/5471478.html
Copyright © 2020-2023  润新知