栈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\n");
 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\n",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\n",St.top());
116     else
117     printf("%.5f\n",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]!='\0'; 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 }

 

posted @ 2020-04-07 17:03  sylvia11  阅读(188)  评论(0编辑  收藏  举报