zoukankan      html  css  js  c++  java
  • 栈ADT应用:中缀表达式求值

    栈ADT应用:中缀表达式求值

    表达式求值是进行数据处理的最基本操作。请编写程序完成一个简单算术表达式的求值。要求如下: 

    (1) 运算符包括:+、-、*、-、^(乘方)、括号

    (2)运算量为数值常量,根据自己的能力可以对运算量做不同的约束,例如1位整数、多位整数、实数等(会有不同的测试用例);

    输入:一行,即表达式,以“=”结束。例如:

               5*(8-3)+6/5=

    输出:一行,即表达式的值。结果值为整数时输出为整数,如果有小数时保留5位小数。

               26.20000

    例如:

    输入Result
    5+(3-1)/2=
    6
    方法一:先转为后缀,再对后缀求值

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3  
      4 const int N = 1e6+50;
      5 char s[N];
      6  
      7 void error()
      8 {
      9     printf("NO
    ");
     10     exit(0);
     11 }
     12  
     13 struct ss
     14 {
     15     double num;
     16     char sign;
     17     int vis;
     18 };
     19  
     20 int main()
     21 {
     22     map<char,int>Map;
     23     Map['+']=Map['-']=1;
     24     Map['*']=Map['/']=2;
     25     Map['^']=3;
     26     Map['(']=Map[')']=0;
     27      
     28     stack<char>Stack;
     29     vector<ss>suff;
     30     scanf("%s",s);
     31     int len=strlen(s)-1;
     32  
     33     for(int i=0;i<len;i++)
     34     {
     35         if(s[i]=='(')Stack.push('(');
     36         else
     37         if(s[i]>='0'&&s[i]<='9')
     38         {
     39             if(s[i]=='0')error();
     40             double now=0;
     41             while(i<len&&s[i]>='0'&&s[i]<='9'){now=now*10+s[i]-'0';i++;}
     42             
     43             if(i<len&&s[i]=='.')
     44             {
     45                 double base=0.1;
     46                 i++;
     47                 while(i<len&&s[i]>='0'&&s[i]<='9')
     48                 {
     49                     now+=base*(s[i]-'0');
     50                     base*=0.1;
     51                     i++;
     52                 }
     53             }
     54             
     55             i--;
     56             suff.push_back((ss){now,0,0});
     57         }
     58         else
     59         if(s[i]==')')
     60         {
     61             while(!Stack.empty()&&Stack.top()!='('){suff.push_back((ss){0,Stack.top(),1});Stack.pop();}
     62             if(!Stack.empty()&&Stack.top()=='(')Stack.pop();
     63             else error();
     64         }
     65         else
     66         if(s[i]=='.')error();
     67         else
     68         {
     69             if(s[i]=='-')
     70             if(i==0||s[i-1]=='(')suff.push_back((ss){0,0,0});
     71              
     72             while(!Stack.empty()&&Map[Stack.top()]>=Map[s[i]])
     73             {suff.push_back((ss){0,Stack.top(),1});Stack.pop();}
     74             Stack.push(s[i]);
     75         }
     76     }
     77      
     78     while(!Stack.empty())
     79     {
     80         if(Stack.top()=='(')error();
     81         else
     82         {suff.push_back((ss){0,Stack.top(),1});Stack.pop();}
     83     }
     84      
     85     double ans=0;
     86     int n=suff.size();
     87     stack<double>St;
     88     for(int i=0;i<n;i++)
     89     {
     90     //  printf("%lld %c
    ",suff[i].num,suff[i].sign);   
     91         if(suff[i].vis==0)St.push(suff[i].num);
     92         else
     93         {
     94             if(St.size()<2)error();
     95             double b=St.top();St.pop(); 
     96             double a=St.top();St.pop(); 
     97             if(suff[i].sign=='-')St.push(a-b);
     98             else
     99             if(suff[i].sign=='+')St.push(a+b);
    100             else
    101             if(suff[i].sign=='*')St.push(a*b);
    102             else
    103             if(suff[i].sign=='/')St.push(a/b);
    104             else
    105             if(suff[i].sign=='^')
    106             {
    107                 double re=1;
    108                 while(b--)re*=a;
    109                 St.push(re);
    110             }
    111         }
    112     }
    113      
    114     if(St.size()!=1)error();
    115     if(St.top()==floor(St.top()))printf("%.0f
    ",St.top());
    116     else
    117     printf("%.5f
    ",St.top());
    118     return 0;
    119 } 
    方法二:直接对后缀求值

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int pre(char c)
     4 {
     5     if(c=='=')
     6         return 0;
     7     else if(c=='+'||c=='-')
     8         return 1;
     9     else if(c=='*'||c=='/')
    10         return 2;
    11     else if(c=='^')
    12         return 3;
    13     return 0;
    14 }
    15 void answer(stack<double> &num,stack<char> &op)
    16 {
    17     double b=num.top();
    18     num.pop();
    19     double a=num.top();
    20     num.pop();
    21     switch(op.top())
    22     {
    23     case '+':
    24         num.push(a+b);
    25         break;
    26     case '-':
    27         num.push(a-b);
    28         break;
    29     case '*':
    30         num.push(a*b);
    31         break;
    32     case '/':
    33         num.push(a/b);
    34         break;
    35     case '^':
    36         num.push(pow(a,b));
    37         break;
    38     }
    39     op.pop();
    40 }
    41 int main()
    42 {
    43     stack<double> num;
    44     stack<char> op;
    45     char s[1005];
    46     scanf("%s",s);
    47     for(int i=0; s[i]!=''; i++)
    48     {
    49         if(isdigit(s[i]))
    50         {
    51             double temp=atof(&s[i]);
    52             num.push(temp);
    53             while(isdigit(s[i])||s[i]=='.')
    54                 i++;
    55             i--;
    56         }
    57         else
    58         {
    59             if(s[i]=='(')
    60                 op.push(s[i]);
    61             else if(s[i]==')')
    62             {
    63                 while(op.top()!='(')
    64                     answer(num,op);
    65                 op.pop();
    66             }
    67             else if(op.empty()||pre(s[i])>pre(op.top()))
    68                 op.push(s[i]);
    69 
    70             else if(!op.empty()&&pre(s[i])<=pre(op.top()))
    71             {
    72                 while(!op.empty()&&pre(s[i])<=pre(op.top()))
    73                     answer(num,op);
    74                 op.push(s[i]);
    75             }
    76         }
    77     }
    78     double ans=num.top();
    79     if((ans-(int)ans)<0.001)
    80         printf("%d",(int)ans);
    81     else
    82         printf("%.5f",ans);
    83     num.pop();
    84     op.pop();
    85     return 0;
    86 }
  • 相关阅读:
    java中&和&&是怎么运算的
    struts中ActionForward 使用mapping.findForward如何传递get参数
    EL表达式_详解
    JSTL标签_详解
    inner join, left join, right join, full join 的区别
    CentOS7部署FastDFS+nginx模块
    一个实例明白AutoResetEvent和 ManulResetEvent的用法
    C#防止在画面上闪烁的Button
    C#中给Label控件设置BackgroundImage属性
    浅析C#异步操作
  • 原文地址:https://www.cnblogs.com/sylvia1111/p/12654411.html
Copyright © 2011-2022 走看看