簡體   English   中英

C ++調車場算法和表達式樹實現

[英]C++ shunting yard algorithm and expression tree implementation

我是C ++的新手,並使用調車場算法構建表達式樹。 我被這個問題困擾了幾天。 我試圖獲取根節點的值,但失敗。


中綴輸入

(1+2)*(3/4)-(5+6)

下面的代碼是基於縮碼的功能:

vector<string> infixToRPN(vector<string> tokens) {
    vector<string> output;
    stack<string> stack;
    string o1;
    string o2;
    //traverse tokens
    for (int i = 0; i < tokens.size(); ++i) {

        // if token is operator
        if (isOperator(tokens[i])) {
            string o1 = tokens[i];
            if (!stack.empty()) {
                string o2 = stack.top();
                while (isOperator(o2) && comparePrecendence(o1, o2) <= 0) {
                    // pop off o2 and on to the output;
                    stack.pop();
                    output.push_back(o2);
                    if (!stack.empty())
                        o2 = stack.top();
                    else
                        break;
                }

            }
            //push o1 on to the stack;
            stack.push(o1);

        }
        //if token is left bracket
        else if (tokens[i] == "(") {
            stack.push(tokens[i]);
        }
        //if token is right bracket
        else if (tokens[i] == ")") {
            string topToken = stack.top();
            while (stack.top() != "(") {
                output.push_back(topToken);
                stack.pop();
                if (stack.empty()) break;
                topToken = stack.top();
            }
            if (!stack.empty()) stack.pop();

        }
        // if token is number and add it to ouput;
        else
        {
            output.push_back(tokens[i]);
        }
    }
    //pop the rest of token
    while (!stack.empty()) {
        string restToken = stack.top();
        output.push_back(restToken);
        stack.pop();
    }
    return output;
}

測試結果表明解析器似乎可以正常工作:

12+34/*56+-

因此,我猜該錯誤可能發生在我的buildTree函數中。 建立之后,getRoot()函數返回的值始終與正確的值不一致。 在我的情況下,根應該為“-”,而我得到的是“ 0”。

 ExprTree ExprTree::buildTree(vector<string> tokens){
    ExprTree t ;
    TreeNode * n, * n1, * n2;
    TreeNode * r = t.getRoot();
    vector<string> postfix = infixToRPN(tokens);
    stack<TreeNode *> stack;
    for (int i = 0; i < postfix.size(); ++i) {
        //if number


        if (!isOperator(postfix[i])) {
            n = createOperatorNode(postfix[i]);
            stack.push(n);
        }
        else // if operator
        {   
            n= createOperatorNode(postfix[i]);
            if (!stack.empty())
                t = ExprTree(stack.top());
            // pop two tree nodes 
            n1 = stack.top();
            stack.pop();
            n2 = stack.top();
            stack.pop();
            //set children nodes;
            n->setLeftChild(n2);
            n->setRightChild(n1);

            stack.push(n);

        }

    }

    return t;
}

您的算法看起來不錯,但是返回的樹有錯誤。

從RPN表示法構建節點之后,堆棧中應該只剩下一個節點。 返回該節點或以該節點為根的樹。

因此,基本上:

for (int i = 0; i < postfix.size(); ++i) {
   // build tree
}

// enforce that there is only one node on the stack

return ExprTree(stack.top());

您也可以隨時跟蹤頂部,但是如果這樣做,則必須使新的運算符節點位於頂部。 在代碼中,將右操作數放在頂部。

請注意,在這種情況下,在處理數字時,還應跟蹤頂部,否則當表達式僅包含數字時,頂部節點將為空。 還要注意,如果操作正確,yourtop將始終是推送到堆棧上的最后一個項目-換句話說,堆棧的頂部。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM