今天,秀华要做中缀表达式,在公司简单地跟她说了一下思路,没怎么细想。晚上回到家,想拿这个进行练笔,看看现在自己的水平怎么样了。
没想到折腾了半天才弄出来,水平真的菜了,唉。。。
- // Expression.hxx
- #ifndef _Expression_HeaderFile
- #define _Expression_HeaderFile
- #include <string>
- #include <stack>
- class Expression {
- private:
- std::string m_sValue;
- std::stack<char> m_staOperators;
- std::stack<double> m_staOperands;
- public:
- //! Construction
- Expression(const std::string &sExp);
- public:
- //! Expression string
- const std::string &toString() const { return m_sValue; }
- //! go computation
- double compute();
- private:
- //! the PRI of cOpt
- int getPRI(const char cOpt) const;
- //! pop two operands from m_staOperands, and compute the expression which
- // algorithm have been defined by m_staOperators.top()
- void computeTwoOperands();
- };
- #endif // _Expression_HeaderFile
- // Expression.cxx
- #include "Expression.hxx"
- #include <sstream>
- /******************************************************************************/
- Expression::Expression(const std::string &sExp)
- : m_sValue(sExp)
- {
- }
- /******************************************************************************/
- int
- Expression::getPRI(const char cOpt) const {
- switch (cOpt) {
- case '$': return 0;
- case '*':
- case '/': return 1;
- case '+':
- case '-': return 2;
- case ')': return 3;
- case '(': return 4;
- case ']': return 5;
- case '[': return 6;
- case '}': return 7;
- case '{': return 8;
- }
- return -1;
- }
- /******************************************************************************/
- double
- Expression::compute() {
- std::istringstream iss(m_sValue);
- char cOpt;
- double rOperand;
- iss >> cOpt;
- while (!iss.eof()) {
- switch (cOpt) {
- case '(':
- case '[':
- case '{':
- m_staOperators.push(cOpt);
- break;
- case ')':
- case ']':
- case '}':
- while (!m_staOperators.empty() && getPRI(cOpt) >= getPRI(m_staOperators.top()))
- computeTwoOperands();
- m_staOperators.pop();
- break;
- case '*':
- case '/':
- case '+':
- case '-':
- if (!m_staOperators.empty() && getPRI(cOpt) >= getPRI(m_staOperators.top()))
- computeTwoOperands();
- }
- m_staOperators.push(cOpt);
- break;
- default:
- iss.putback(cOpt);
- iss >> rOperand;
- m_staOperands.push(rOperand);
- break;
- }
- iss >> cOpt;
- }
- while (!m_staOperators.empty())
- computeTwoOperands();
- if (m_staOperands.size() == 1)
- return m_staOperands.top();
- return 0;
- }
- /******************************************************************************/
- void
- Expression::computeTwoOperands() {
- if (m_staOperands.size() >= 2 && !m_staOperators.empty()) {
- double opRight = 0.;
- opRight = m_staOperands.top();
- m_staOperands.pop();
- switch (m_staOperators.top()) {
- case '*':
- m_staOperands.top() *= opRight;
- m_staOperators.pop();
- break;
- case '/':
- m_staOperands.top() /= opRight;
- m_staOperators.pop();
- break;
- case '+':
- m_staOperands.top() += opRight;
- m_staOperators.pop();
- break;
- case '-':
- m_staOperands.top() -= opRight;
- m_staOperators.pop();
- break;
- default:
- break;
- }
- }
- }
- // Calculator.cxx : a console application for testing.
- //
- #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
- #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
- #endif
- #include <stdio.h> // for system
- #include <iostream> // for std::cout
- #include "Expression.hxx"
- /******************************************************************************/
- int
- main(int argc, char* argv[]) {
- Expression exp("2*[5+3/(2-1)]*(4-1)");
- std::cout << exp.toString() << " = " << exp.compute() << std::endl;
- Expression exp2("2*3/(2-1)+5*(4-1)");
- std::cout << exp2.toString() << " = " << exp2.compute() << std::endl;
- system("pause");
- return 0;
- }