以前在《The c programming language》 里面看到了个后缀计算器,输入是后缀表达式,输出计算结果。当时还不知道如何把用户容易使用的表达式(中缀)转换成后缀。
后来看了《Data structures and algorithm analysis》,发现 栈 这一章里面讲了一种算法,不是很复杂。于是当时我就把两者组合起来,做了一个很不错的后缀计算器(至少从编程风格上来说)我感觉istringstream是很好用的,相比c中getchar()ungetc()自行管理缓冲区要方便,更不容易出错。
#include <cctype> #include <sstream> #include <string> #include <stack> #include <iostream> using namespace std; int cmp(char,char); string inTopost(string infix) { istringstream in(infix); ostringstream out; stack<char> op; char c; while (in >> c) { if (c == '(') op.push(c); else if (c == ')') { while (!op.empty() && op.top() != '(') { out << op.top() << " "; op.pop(); } if (!op.empty()) op.pop(); //c == '(' } else if (c == '+' || c == '-' || c =='*' || c == '/') { //cmp returns 1 if op.top() >= c while (!op.empty() && cmp(c,op.top())) { out << op.top() << " "; op.pop(); } op.push(c); } else if (isdigit(c)) { in.putback(c); int n; in >> n; out << n << " "; } else cout << "Unkown format" << endl; } while (!op.empty()) { out << op.top() << " "; op.pop(); } return out.str(); } int cmp(char c1,char c2) { switch (c1) { case '-': case '+': return (c2 == '(') ? 0 : 1; break; case '/': case '*': if (c2 == '*' || c2 == '/') return 1; else return 0; break; default: cout << "Unknown OPTR" << endl; } }
#include <cstdlib> #include <iostream> #include <string> #include <sstream> #include <stack> using namespace std; string inTopost(string infix); int main(int argc, char *argv[]) { bool quit = false; double op, op2; stack<double> s1; string infix, postfix, cmd; cout << "Input infix expression you want to calculate:"; getline(cin,infix,'\n'); postfix = inTopost(infix); istringstream in(postfix); while (in >> cmd) { switch(cmd[0]) { case '+': op = s1.top(); s1.pop(); op2 = s1.top(); s1.pop(); s1.push(op + op2); break; case '*': op = s1.top(); s1.pop(); op2 = s1.top(); s1.pop(); s1.push(op * op2); break; case '-': op2 = s1.top(); s1.pop(); op = s1.top(); s1.pop(); s1.push(op - op2); break; case '/': op2 = s1.top(); s1.pop(); if(op2) { op = s1.top(); s1.pop(); s1.push(op / op2); } else cout << "\nError: division by zero!"; break; default: istringstream in2(cmd); in2 >> op; s1.push(op); } } cout << s1.top() << endl ; system("PAUSE"); return EXIT_SUCCESS; }