栈的运用! 表达式求值。
初级版本
http://acm.hdu.edu.cn/showproblem.php?pid=1237
拿杭电的这个初级版本练练手!
1 #include<iostream> 2 #include<algorithm> 3 #include<stdio.h> 4 #include<math.h> 5 #include<string.h> 6 #include<queue> 7 #include<stack> 8 using namespace std; 9 #define maxn 17 10 11 stack <char> opS;//符号栈 12 stack <double> numS;//数字栈 13 char str[300]; 14 int pos[5] = {'+','-', '*', '/', '#' }; 15 int cmps[5][5] = { {1,1,2,2,1}, 16 {1,1,2,2,1}, 17 {1,1,1,1,1}, 18 {1,1,1,1,1}, 19 {2,2,2,2,3} }; 20 21 char* getNum(char *p,double &num) 22 { 23 num = 0; 24 while(*p != ' ' && *p) 25 { 26 num = num*10 + *p - '0'; 27 p ++; 28 } 29 30 if(*p == ' ') 31 p ++; 32 33 return p; 34 } 35 int getOp(char ch) 36 { 37 for(int i=0; i<5; i++) 38 { 39 if(ch == pos[i]) 40 return i; 41 } 42 } 43 44 45 int cmp(char op2,char op) 46 { 47 int a, b; 48 a = getOp(op2); 49 b = getOp(op); 50 51 return cmps[a][b]; 52 } 53 54 double cal(double a, double b,char op) 55 { 56 switch(op) 57 { 58 case '+':return a+b; 59 case '-':return b-a; 60 case '*':return a*b; 61 case '/':return b/a; 62 } 63 64 } 65 66 double solve() 67 { 68 double num1, num2; 69 char op, *p = str, op2; 70 71 opS.push('#'); 72 73 while(*p) 74 { 75 p = getNum(p,num1); 76 77 if(*p) 78 { 79 op = *p; 80 p += 2; 81 } 82 else 83 op = '#'; 84 85 numS.push(num1); 86 87 while(1) 88 { 89 op2 = opS.top(); 90 91 if(cmp(op2,op) == 2)///如果栈内运算符的优先级 比栈外的优先级要低 操作符都入栈 92 { 93 opS.push(op); 94 break; 95 } 96 else if(cmp(op2, op) == 3) 97 { 98 return numS.top(); 99 } 100 else 101 { 102 num1 = numS.top(); 103 numS.pop(); 104 num2 = numS.top(); 105 numS.pop(); 106 opS.pop(); 107 108 num1 = cal(num1, num2, op2); 109 numS.push(num1); 110 } 111 } 112 113 114 } 115 116 } 117 118 int main() 119 { 120 while(gets(str), strcmp(str, "0") ) 121 { 122 while(opS.size() ) 123 opS.pop(); 124 while(numS.size() ) 125 numS.pop(); 126 127 double ans = solve(); 128 129 printf("%.2lf\n", ans); 130 } 131 return 0; 132 }
下面是南阳理工的一个题目属于加强版,第一个写出来后第二个写起来就轻松多了
#include<iostream> #include<algorithm> #include<stdio.h> #include<math.h> #include<string.h> #include<queue> #include<stack> using namespace std; #define maxn 17 char pos[7] = { '+', '-', '*', '/', '(', ')', '=' }; ///运算符的优先级比较 cmp[栈中符号][栈外符号比较] 1 >, 2<, 3 =, 4 不可比 int cmp[7][7] = { {1,1,2,2,2,1,1}, {1,1,2,2,2,1,1}, {1,1,1,1,2,1,1}, {1,1,1,1,2,1,1}, {2,2,2,2,2,3,4}, {4,4,4,4,4,4,4}, {2,2,2,2,2,4,3} }; double getNum(char* &p) { double num; sscanf(p, "%lf", &num); while( (*p >='0' && *p <= '9') || *p == '.' ) p ++; return num; } char getOp(char* &p) { char ch; ch = *p; p ++; return ch; } double cal(double a, double b,char op) { switch(op) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': return a / b; } } int cmps(char op1,char op2) { int a, b; for(int i=0; i<7; i++) { if(pos[i] == op1) a = i; if(pos[i] == op2) b = i; } return cmp[a][b]; } double solve(char *p) { stack <char> opS;///符号栈 stack <double> numS;///数字栈 double num1, num2; char op1, op2; opS.push('='); while(1) { if(*p >= '0' && *p <= '9') numS.push( getNum(p) ); op2 = getOp(p); while(1) { op1 = opS.top(); if( cmps(op1,op2) == 2)///栈中元素的优先级小,将栈外符号入栈 { opS.push(op2); break; } else if( cmps(op1,op2) == 1)///栈中元素的优先级大,将栈中符号拿出来运算 { opS.pop(); num1 = numS.top(); numS.pop(); num2 = numS.top(); numS.pop(); numS.push( cal(num2, num1, op1) ); } else if( cmps(op1, op2) == 3 ) { opS.pop(); if(op1 == '(' ) break; if(op1 == '=') return numS.top(); } } } } int main() { int T; char str[1350]; scanf("%d ", &T); while(T--) { scanf("%s", str); double ans = solve(str); printf("%.2lf\n", ans); } return 0; }