[C/C++基礎]- 利用標準C++工具開發簡易數學直譯器
本篇要分享利用標準C++工具開發簡易數學直譯器,有興趣的(C/P)同好,歡迎來(C/P)一下哈哈 ^ ^ 。
程式碼 |
#include <cstdlib> #include <iostream> #include <string> // string #include <sstream> // stringstream #include <stack> // stack #include <vector> // vector #include <cctype> // isdigit() usingnamespace std; // define const variable for readability constint OPERATOR = 0; constint OPERAND = 1; class Expression { // constructor public: Expression(); Expression(constchar*); // public member function public: double eval(); // get eval result // private data member private: stack<double> operandStack; // stack to store operand stack<char> operatorStack; // stack to store operator string infix; // string to hold infix expression vector<pair<int, string> > suffix; // vector to hold suffix expression // private member function private: string char2str(constchar &); // convert char to string string dbl2str(constdouble &); // convert double to string double str2dbl(const string &); // convert string to double bool isoperator(constchar &); // identify whether it is an operator void parseOperand(constdouble &); // parse operand to operandStack void parseOperator(constchar &); // parse operator to operatorStack int operatorPriority(constchar&); // define operator priority void toSuffix(void); // convert infix to suffix double calculate(const string &, constdouble &, constdouble &); // calculate result by operator and operand }; // constructor Expression::Expression() { } // constructor Expression::Expression(constchar *val) { this->infix = string(val); // fill infix by constructor this->toSuffix(); // convert infix to suffix } // convert char to string string Expression::char2str(constchar &c) { stringstream ss; ss << c; return ss.str(); } // convert double to string string Expression::dbl2str(constdouble &d) { stringstream ss; ss << d; return ss.str(); } // convert string to double double Expression::str2dbl(const string &s) { stringstream ss(s); double d; ss >> d; return d; } // identify whether it is an operator bool Expression::isoperator(constchar &c) { switch(c) { case '(' : case ')' : case '+' : case '-' : case '*' : case '/' : returntrue; default : returnfalse; } } // parse operand to operandStack void Expression::parseOperand(constdouble &dOperand) { suffix.push_back(make_pair(OPERAND, dbl2str(dOperand))); } // parse operator to operatorStack void Expression::parseOperator(constchar &cOperator) { if (operatorStack.empty() || cOperator == '(') { operatorStack.push(cOperator); } else { if (cOperator == ')') { while(operatorStack.top() != '(') { suffix.push_back(make_pair(OPERATOR, char2str(operatorStack.top()))); operatorStack.pop(); if (operandStack.empty()) break; } // Remove '(' operatorStack.pop(); } else { // not ')' while(operatorPriority(cOperator) <= operatorPriority(operatorStack.top()) && !operatorStack.empty()) { suffix.push_back(make_pair(OPERATOR, char2str(operatorStack.top()))); operatorStack.pop(); if (operatorStack.empty()) break; } operatorStack.push(cOperator); } } } // define operator priority int Expression::operatorPriority(constchar &cOperator) { switch(cOperator) { case '*' : case '/' : return 3; case '+' : case '-' : return 2; case '(' : return 1; default : return 0; } } // Convert infix to suffix // Algorithm : Parse infix string one char by one char. If char // is operator, check if _operand is "", if not, let // _operand to operandStack, and make _operand string // clear, then let operator to operatorStack. If char // is digit, concatenate to _operand string. void Expression::toSuffix(void) { string _operand; for(string::iterator p = infix.begin(); p != infix.end(); ++p) { if (isoperator(*p)) { if (_operand != "") { parseOperand(str2dbl(_operand)); _operand.clear(); } parseOperator(*p); } elseif (isdigit(*p)) _operand.push_back(*p); } // If _operand is not "", let _operand to operandStack. if (_operand != "") parseOperand(str2dbl(_operand)); // If operatorStack is not empty, push it to suffix vector until // operatorStack is empty. while(!operatorStack.empty()) { suffix.push_back(make_pair(OPERATOR,char2str(operatorStack.top()))); operatorStack.pop(); } } // calculate result by operator and operand double Expression::calculate(const string &op, constdouble &operand1, constdouble &operand2) { if (op == "+") return operand2 + operand1; elseif (op == "-") return operand2 - operand1; elseif (op == "*") return operand2 * operand1; elseif (op == "/") return operand2 / operand1; else return 0; } // get eval result double Expression::eval(void) { // Clear OperandStack while(!operandStack.empty()) operandStack.pop(); for(vector<pair<int, string> >::iterator iter = suffix.begin(); iter != suffix.end(); ++iter) { if (iter->first == OPERATOR) { double operand1 = operandStack.top(); operandStack.pop(); double operand2 = operandStack.top(); operandStack.pop(); operandStack.push(calculate(iter->second, operand1, operand2)); } elseif (iter->first == OPERAND) { operandStack.push(str2dbl(iter->second)); } } return operandStack.top(); } int main(int argc, char *argv[]) { Expression x1("10+20*5"); cout << "x1=" << x1.eval() << endl; Expression x2("5*20+10+1+2-3+99"); cout << "x2=" << x2.eval() << endl; system("PAUSE"); return EXIT_SUCCESS; }
|
沒有留言:
張貼留言