運算式求值(二叉樹方法/C++語言描述)(二)

來源:互聯網
上載者:User

標籤:指示   代碼   numbers   ase   png   com   rac   ken   union   

  運算式二叉樹節點的資料可能是運算數或運算子,可以使用一個聯合體進行儲存;同時還需要一個變數來指示儲存的是運算數還是運算子,可以採用和棧方法中一樣的枚舉類型TokenType:

 1 typedef enum 2 { 3     BEGIN, 4     NUMBER, 5     OPERATOR, 6     LEFT_BRAC, 7     RIGHT_BRAC 8 } TokenType; 9 10 class Token11 {12 public:13     TokenType _type;14     union15     {16         char op;17         double num;18     } _data;19 };

  二叉樹方法的Calculator類則公有繼承自節點資料資料類型為Token類的BinaryTree類:

 1 class Calculator : public BinaryTree<Token> 2 { 3 public: 4     void parseExpression(string expression) throw(string); 5     double calculate(); 6  7 private: 8     stack<char> _stkOperators; 9     stack<BinaryTreeNode<Token> *> _stkNodes;10     stack<double> _stkNumbers;11 12     static int priority(char op);13     static double calculate(double d1, char op, double d2) throw(string);14 15     void postOrder(BinaryTreeNode<Token> * node);16     void calculateStack() throw(string);17     void dealWithNumber(char *&pToken) throw(string);18     void dealWithOperator(char *&pToken) throw(string);19     void dealWithLeftBrac(char *&pToken) throw(string);20     void dealWithRightBrac(char *&pToken) throw(string);21 };

方法parseExpression()用來將運算式轉換為二叉樹,它需要兩個棧,一個用來儲存運算子,一個用來儲存指向子樹的指標;用來儲存浮點類型的棧僅在求值時使用。

  轉換過程與棧方法的運算壓棧過程基本相同,當遇到運算數時,產生一個新的節點並將它的指標壓入節點指標棧中;遇到運算子時比較當前運算子和運算子棧棧頂運算子的優先順序,若運算子棧棧頂運算子的優先順序較高,則為它產生一個新的節點,並從節點指標棧中彈出兩個節點指標,作為新節點的左子樹和右子樹,最後將這個新節點的指標壓入節點指標棧中,將當前運算子壓入運算子棧中,否則只將當前運算子壓入運算子棧中。最後反覆執行上述過程,直至運算子棧為空白,節點指標棧的棧頂元素即為指向樹根節點的指標。運算式“1+2*3”和“1*2+3”的轉換過程如:

 

使用代碼描述動作節點指標棧的過程:

 1 void Calculator::calculateStack() throw(string) 2 { 3     BinaryTreeNode<Token> * node = new BinaryTreeNode<Token>(); 4     assert(node); 5     node->_data._type = OPERATOR; 6     node->_data._data.op = _stkOperators.top(); 7     _stkOperators.pop(); 8     assert(!_stkNodes.empty()); 9     node->_rightChild = _stkNodes.top();10     _stkNodes.pop();11     assert(!_stkNodes.empty());12     node->_leftChild = _stkNodes.top();13     _stkNodes.pop();14     _stkNodes.push(node);15 }

  根據數學規則和最後清空運算子棧的過程,parseExpression()方法實現如下:

 1 void Calculator::parseExpression(string expression) throw(string) 2 { 3     destory(); 4     while (!_stkNodes.empty()) 5     { 6         _stkNodes.pop(); 7     } 8     while (!_stkOperators.empty()) 9     {10         _stkOperators.pop();11     }12     TokenType lastToken = BEGIN;13 14     char * pToken = &expression[0];15     while (*pToken)16     {17         switch (lastToken)18         {19         case BEGIN:20             if (*pToken == ‘(‘)21             {22                 // an expression begin with a left bracket23                 dealWithLeftBrac(pToken);;24                 lastToken = LEFT_BRAC;25             }26             else27             {28                 // or a number29                 dealWithNumber(pToken);30                 lastToken = NUMBER;31             }32             break;33         case NUMBER:34             // after a number35             if (*pToken == ‘)‘)36             {37                 // it may be a right bracket38                 dealWithRightBrac(pToken);39                 lastToken = RIGHT_BRAC;40             }41             else42             {43                 // it may be an operator44                 dealWithOperator(pToken);45                 lastToken = OPERATOR;46             }47             break;48         case OPERATOR:49         case LEFT_BRAC:50             // after an operator or a left bracket51             if (*pToken == ‘(‘)52             {53                 // it may be a left bracket54                 dealWithLeftBrac(pToken);55                 lastToken = LEFT_BRAC;56             }57             else58             {59                 // it may be a number60                 dealWithNumber(pToken);61                 lastToken = NUMBER;62             }63             break;64         case RIGHT_BRAC:65             // after a right bracket66             if (*pToken == ‘)‘)67             {68                 // it may be another right bracket69                 dealWithRightBrac(pToken);70                 lastToken = RIGHT_BRAC;71             }72             else73             {74                 // it may be an perator75                 dealWithOperator(pToken);76                 lastToken = OPERATOR;77             }78             break;79         }80     }81 82     while (!_stkOperators.empty())83     {84         if (_stkOperators.top() == ‘(‘)85         {86             throw string("bad token ‘(‘");87         }88         calculateStack();89     }90 91     assert(!_stkNodes.empty());92     _root = _stkNodes.top();93 }

方法實現與棧方法求值的公有方法calculator()基本相同。開始調用的destory()方法繼承自BinaryTree類,用於釋放已佔用的二叉樹節點空間,可以防止程式記憶體溢出。

運算式求值(二叉樹方法/C++語言描述)(二)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.