1. 程式人生 > >表達式求值(二叉樹方法/C++語言描述)(三)

表達式求值(二叉樹方法/C++語言描述)(三)

urn sse 二叉 返回 新的 求值 calc ken node

  二叉樹方法求值對運算數處理的方法與棧方法求值不太相同,除了將字符串中的運算數轉換為浮點類型外,還需要生成新的節點:

 1 void Calculator::dealWithNumber(char *&pToken) throw(string)
 2 {
 3     if (!isdigit(*pToken) && *pToken != -)
 4     {
 5         throw string("bad token ‘") + *pToken + "";
 6     }
 7 
 8     BinaryTreeNode<Token> * node = new
BinaryTreeNode<Token>(); 9 assert(node); 10 node->_data._type = NUMBER; 11 node->_data._data.num = strtod(pToken, &pToken); 12 node->_leftChild = node->_rightChild = nullptr; 13 _stkNodes.push(node); 14 }

  對其他token的處理則和棧方法求值類似,請參考代碼清單,這裏不再贅述。

  公有方法calculate()直接調用了postOrder()方法,調用前清空用於存儲浮點類型的棧,方法返回後這個棧的棧頂元素即為運算結果:

double Calculator::calculate()
{
    while (!_stkNumbers.empty())
    {
        _stkNumbers.pop();
    }

    BinaryTree::postOrder();

    assert(!_stkNumbers.empty());
    return _stkNumbers.top();
}

  postOrder()方法重寫了從BinaryTree類繼承的postOrder()方法,它在後序遍歷時遇到運算數則壓棧,遇到運算符則彈棧計算:

 1 void Calculator::postOrder(BinaryTreeNode<Token> *node)
2 { 3 if (node) 4 { 5 postOrder(node->_leftChild); 6 postOrder(node->_rightChild); 7 // visit binary tree data 8 if (node->_data._type == NUMBER) 9 { 10 _stkNumbers.push(node->_data._data.num); 11 } 12 else 13 { 14 assert(!_stkNumbers.empty()); 15 double d2 = _stkNumbers.top(); 16 _stkNumbers.pop(); 17 assert(!_stkNumbers.empty()); 18 double d1 = _stkNumbers.top(); 19 _stkNumbers.pop(); 20 char op = node->_data._data.op; 21 _stkNumbers.push(calculate(d1, op, d2)); 22 } 23 } 24 }

靜態方法calculate()與棧方法求值中的也相同。

  最後編寫主函數,大功告成!

表達式求值(二叉樹方法/C++語言描述)(三)