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 }
参考大神博客后,AC了的总结。
不喜勿喷,欢迎赐教,欢迎一起交流