经典算法问题-表达式求值
上次和同事聊到了验证码中有表达式求值的问题,说起来应该是比较简单了,也是数据结构上经典的算法问题。可是自己写一写才会发现,做对一件看似简单的事情不是那么容易。
本来自己弄了一个c的stack,但是c没有模板,想不到怎么支持不同的类型,只好换用c++了。
#include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <stack> #include <iostream> using namespace std; /** * 比较运算符之间的优先级 */ static short int Precede(char c1, char c2) { if (c1 == c2) { if (c1 == '#') { return 0; } else if(c1 == '(') { return -1; } else { return 1; } } switch (c1) { case '+': case '-': if (c2 == '*' || c2 == '/' || c2 == '(') { return -1; } else { return 1; } break; case '*': case '/': if (c2 == '(') { return -1; } else { return 1; } break; case '(': if (c2 == ')') { return 0; } else { return -1; } break; case ')': return 1; break; case '#': return -1; } } /** * 对加减乘除进行求值 */ static float Operate(float a, char theta, float b) { switch (theta) { case '+': return a+b; break; case '-': return a-b; break; case '*': return a*b; break; case '/': return a/b; break; } printf("bad operator"); return 0; } int main() { stack<char> optr; stack<float> opnd; optr.push('#'); char theta, tmp[20], *tmppoint, basechar[20]; tmppoint = basechar; float a, b; char c = getchar(); while (c!='#' || optr.top() != '#') { if (isdigit(c)) { *(tmppoint++) = c; c = getchar(); } else { if (tmppoint > basechar) { *tmppoint = ''; opnd.push(atof(basechar)); printf ("push number %s\n", basechar); tmppoint = basechar; } if (c != '+' && c != '-' && c != '*' && c != '/' && c != '(' && c != ')' && c != '#' ) { c = getchar(); continue; } short int precede = Precede(optr.top(), c); switch (precede) { case -1: optr.push(c); printf("pushed operator %c \n", c); c = getchar(); break; case 0: optr.pop(); c = getchar(); break; case 1: theta = optr.top(); optr.pop() ; if (opnd.empty()) { printf("opnd is empty\n"); } b = opnd.top(); opnd.pop(); a = opnd.top(); opnd.pop(); cout << " cal a=" << (float)a << " theta=" << theta << " b=" << (float)b << endl; opnd.push(Operate(a, theta, b)); break; } } } /* 最后的结果 */ printf("%f\n", opnd.top()); printf("%c\n", optr.top()); return 0; }