栈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 }