[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 readabilityconstint OPERATOR = 0; constint OPERAND = 1; class Expression { // constructorpublic: Expression();Expression(constchar*); // public member functionpublic: double eval(); // get eval result // private data memberprivate: 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 functionprivate: 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 }; // constructorExpression::Expression() { } // constructorExpression::Expression(constchar *val) { this->infix = string(val); // fill infix by constructor this->toSuffix(); // convert infix to suffix } // convert char to stringstring Expression::char2str(constchar &c) { stringstream ss; ss << c; return ss.str(); } // convert double to stringstring Expression::dbl2str(constdouble &d) { stringstream ss; ss << d; return ss.str(); } // convert string to doubledouble Expression::str2dbl(const string &s) { stringstream ss(s);double d; ss >> d; return d; } // identify whether it is an operatorbool Expression::isoperator(constchar &c) { switch(c) { case '(' : case ')' : case '+' : case '-' : case '*' : case '/' : returntrue; default : returnfalse; }} // parse operand to operandStackvoid Expression::parseOperand(constdouble &dOperand) { suffix.push_back(make_pair(OPERAND, dbl2str(dOperand)));} // parse operator to operatorStackvoid 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 priorityint 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 operanddouble 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 resultdouble 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; }
|
沒有留言:
張貼留言