中缀表达式计算



今天,秀华要做中缀表达式,在公司简单地跟她说了一下思路,没怎么细想。晚上回到家,想拿这个进行练笔,看看现在自己的水平怎么样了。

没想到折腾了半天才弄出来,水平真的菜了,唉。。。

  1. // Expression.hxx

  2. #ifndef _Expression_HeaderFile
  3. #define _Expression_HeaderFile


  4. #include <string>
  5. #include <stack>


  6. class Expression {

  7. private:
  8.     std::string        m_sValue;

  9.     std::stack<char>   m_staOperators;
  10.     std::stack<double> m_staOperands;

  11. public:
  12.     //! Construction
  13.     Expression(const std::string &sExp);

  14. public:
  15.     //! Expression string
  16.     const std::string &toString() const { return m_sValue; }

  17.     //! go computation
  18.     double compute();

  19. private:
  20.     //! the PRI of cOpt
  21.     int getPRI(const char cOpt) const;

  22.     //! pop two operands from m_staOperands, and compute the expression which
  23.     //   algorithm have been defined by m_staOperators.top()
  24.     void computeTwoOperands();

  25. };

  26. #endif // _Expression_HeaderFile

  1. // Expression.cxx

  2. #include "Expression.hxx"
  3. #include <sstream>


  4. /******************************************************************************/
  5. Expression::Expression(const std::string &sExp)
  6.     : m_sValue(sExp)
  7. {
  8. }

  9. /******************************************************************************/
  10. int
  11. Expression::getPRI(const char cOpt) const {

  12.     switch (cOpt) {
  13.         case '$':   return 0;
  14.         case '*':
  15.         case '/':   return 1;
  16.         case '+':
  17.         case '-':   return 2;
  18.         case ')':   return 3;
  19.         case '(':   return 4;
  20.         case ']':   return 5;
  21.         case '[':   return 6;
  22.         case '}':   return 7;
  23.         case '{':   return 8;
  24.     }

  25.     return -1;

  26. }

  27. /******************************************************************************/
  28. double
  29. Expression::compute() {

  30.     std::istringstream iss(m_sValue);

  31.     char   cOpt;
  32.     double rOperand;

  33.     iss >> cOpt;

  34.     while (!iss.eof()) {

  35.         switch (cOpt) {

  36.             case '(':
  37.             case '[':
  38.             case '{':
  39.                 m_staOperators.push(cOpt);
  40.             break;

  41.             case ')':
  42.             case ']':
  43.             case '}':
  44.                 while (!m_staOperators.empty() && getPRI(cOpt) >= getPRI(m_staOperators.top()))
  45.                     computeTwoOperands();

  46.                 m_staOperators.pop();
  47.             break;

  48.             case '*':
  49.             case '/':
  50.             case '+':
  51.             case '-':
  52.                 if (!m_staOperators.empty() && getPRI(cOpt) >= getPRI(m_staOperators.top()))
  53.                     computeTwoOperands();

  54.                 }

  55.                 m_staOperators.push(cOpt);
  56.             break;

  57.             default:
  58.                 iss.putback(cOpt);
  59.                 iss >> rOperand;

  60.                 m_staOperands.push(rOperand);
  61.             break;

  62.         }

  63.         iss >> cOpt;

  64.     }

  65.     while (!m_staOperators.empty())
  66.         computeTwoOperands();

  67.     if (m_staOperands.size() == 1)
  68.         return m_staOperands.top();

  69.     return 0;

  70. }

  71. /******************************************************************************/
  72. void
  73. Expression::computeTwoOperands() {

  74.     if (m_staOperands.size() >= 2 && !m_staOperators.empty()) {

  75.         double opRight = 0.;

  76.         opRight = m_staOperands.top();
  77.         m_staOperands.pop();

  78.         switch (m_staOperators.top()) {

  79.             case '*':
  80.                 m_staOperands.top() *= opRight;
  81.                 m_staOperators.pop();
  82.             break;

  83.             case '/':
  84.                 m_staOperands.top() /= opRight;
  85.                 m_staOperators.pop();
  86.             break;

  87.             case '+':
  88.                 m_staOperands.top() += opRight;
  89.                 m_staOperators.pop();
  90.             break;

  91.             case '-':
  92.                 m_staOperands.top() -= opRight;
  93.                 m_staOperators.pop();
  94.             break;

  95.             default:
  96.             break;

  97.         }

  98.     }

  99. }

  1. // Calculator.cxx : a console application for testing.
  2. //

  3. #ifndef _WIN32_WINNT                // Allow use of features specific to Windows XP or later.
  4.     #define _WIN32_WINNT 0x0501     // Change this to the appropriate value to target other versions of Windows.
  5. #endif

  6. #include <stdio.h>  // for system
  7. #include <iostream> // for std::cout

  8. #include "Expression.hxx"


  9. /******************************************************************************/
  10. int
  11. main(int argc, char* argv[]) {

  12.     Expression exp("2*[5+3/(2-1)]*(4-1)");
  13.     std::cout << exp.toString() << " = " << exp.compute() << std::endl;

  14.     Expression exp2("2*3/(2-1)+5*(4-1)");
  15.     std::cout << exp2.toString() << " = " << exp2.compute() << std::endl;

  16.     system("pause");
  17.     return 0;

  18. }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值