标签:
本文的主要内容是如何求一个给定的表达式的值,具体思路就是先将普通算术的中缀表达式转化为后缀表达式,这一步用到的算法叫做调度场算法。然后对后缀表达式,也就是逆波兰表达式求值。
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3596
代码:(参考别人的重构)
#include <iostream> #include <string.h> #include <stdio.h> #include <math.h> #include <stack> #include <map> #define N 10005 #define EPS 1e-9 using namespace std; struct Node { double val; char opt; Node(double val = 0, char opt = ' ') { this->val = val; this->opt = opt; } }; Node node[N]; char str[N]; map<char, int> mp; void Init() { mp['('] = 0; mp['-'] = mp['+'] = 1; mp['*'] = mp['/'] = 2; mp['^'] = 3; } //逆波兰表达式的计算 double CalPoland(Node node[], int n) { stack<double> s; for(int i = 0; i < n; i++) { if(node[i].opt == ' ') s.push(node[i].val); else { double a = s.top(); s.pop(); double b = s.top(); s.pop(); switch(node[i].opt) { case '+': s.push(b + a); break; case '-': s.push(b - a); break; case '*': s.push(b * a); break; case '/': if(fabs(a) < EPS) throw true; s.push(b / a); break; case '^': s.push(pow(b, a)); break; } } } return s.top(); } //调度场算法 double ShuntYardAlgo(char str[]) { stack<char> oper; //inNum标记当前是否可以输入数字 bool inNum = true; //hasDot标记是否已经输入小数点 bool hasDot = true; int p = 0; //扫描指针位置 int cnt = 0; //符号或者数字计数器 int sign = 1; //表示正负符号 while(str[p]) { if(isdigit(str[p]) || str[p] == '.') { if(inNum) { double val = 0; double w = 1; if(str[p] == '.') { hasDot = true; val = 0; } else { hasDot = false; val = str[p] - '0'; } p++; while(isdigit(str[p]) || str[p] == '.') { if(str[p] == '.') { if(hasDot) throw true; hasDot = true; } else { if(hasDot) { w *= 0.1; val += (str[p] - '0') * w; } else val = val * 10 + str[p] - '0'; } p++; } p--; node[cnt++] = Node(val * sign, ' '); sign = 1; inNum = false; } else throw true; } else { switch(str[p]) { case '(': oper.push(str[p]); break; case ')': while(!oper.empty() && oper.top() != '(') { node[cnt++] = Node(0, oper.top()); oper.pop(); } if(oper.empty()) throw true; oper.pop(); break; case '+': case '-': case '*': case '/': case '^': if(inNum) { if(str[p] != '+' && str[p] != '-') throw true; while(str[p] == '+' || str[p] == '-') { if(str[p] == '-') sign *= -1; p++; } p--; } else { while(!oper.empty() && mp[str[p]] <= mp[oper.top()]) { node[cnt++] = Node(0, oper.top()); oper.pop(); } oper.push(str[p]); inNum = true; } break; } } p++; } while(!oper.empty()) { node[cnt++] = Node(0, oper.top()); oper.pop(); } return CalPoland(node, cnt); } int main() { Init(); while(scanf("%s", str) != EOF) { try{ printf("%.8lf\n", ShuntYardAlgo(str)); } catch(bool){ puts("The teacher is so lazy!"); } } return 0; }
标签:
原文地址:http://blog.csdn.net/acdreamers/article/details/46431285