表达式树计算错误

Expression Tree Evaluating Error

本文关键字:错误 计算 表达式      更新时间:2023-10-16

这是我必须为类创建的表达式树,但是调用evaluate函数时不显示任何内容。你知道我哪里做错了,或者我遗漏了什么吗?从我们在课堂上学到的,它看起来应该运行。

#include <iostream>
#include <string>
using namespace std;

class TreeNode                              //Leaf Node
{
public:
    TreeNode(char key, int data, TreeNode* p)   //constructor
    {
                this->key = key;
                this->data = data;
                n = 1;
                left = NULL;
                right = NULL;
                parent = p;
    }

        TreeNode * left;
        TreeNode * right;
        TreeNode * parent;
        char key;
        int data;
        int n;
};
class ExpressionTree                //expression tree
{
public:
    void create();                  //creates binary expression tree
    TreeNode * root;                //instance of TreeNode
    int Evaluate(TreeNode * n);     //evaluates tree
    void InOrder(TreeNode * n);     //traverses tree InOrder
    void PreOrder(TreeNode *n);     //traverses tree PreOrder
    void PostOrder(TreeNode *n);    //traverses tree PostOrder
};
void ExpressionTree::create()       //creates binary expression tree
{
    root = new TreeNode('*',3,0 );
    root->left = new TreeNode('+',5,root);
    root ->left->left = new TreeNode('2',2,root->left);
    root ->left->right = new TreeNode('3',3,root->left);
    root->right = new TreeNode('5',5,root);
}
int ExpressionTree::Evaluate(TreeNode *n) //Evaluates tree
{
    int answer = 0;
    switch(n->key)                       //switch statement to decide what operator is being used
            {
                case '+':
                    answer = (Evaluate(n->left)+ Evaluate(n->right));
                    break;
                case '-':
                    answer = (Evaluate(n->left)- Evaluate(n->right));
                    break;
                case '*':
                    answer = (Evaluate(n->left)* Evaluate(n->right));
                    break;
                case '/':
                    answer = (Evaluate(n->left)/ Evaluate(n->right));
                    break;
            }
        return answer;                  //returns answer
}
void ExpressionTree::InOrder(TreeNode * n)  //traverses the tree InOrder
{
    if ( n ) {
           InOrder(n->left);
           cout << n->key << " ";
           InOrder(n->right);
        }
}
void ExpressionTree::PreOrder(TreeNode * n) //traverses the tree PreOrder
{
    if ( n ) {
           cout << n->key << " ";
           PreOrder(n->left);
           PreOrder(n->right);
        }
}
void ExpressionTree::PostOrder(TreeNode * n)//traverses the tree PostOrder
{
    if ( n ) {
           PostOrder(n->left);
           PostOrder(n->right);
           cout << n->key << " ";
        }
}
int main()                                  //main program
{
ExpressionTree * mytree;                    //creates instance of ExpressionTree
mytree->create();
cout<<"The Answer is: "<<endl;
mytree->Evaluate(mytree->root);
cout<<endl;
cout<<"In InOrder"<<endl;
mytree->InOrder(mytree->root);
cout<<endl;
cout<<"In PreOrder"<<endl;
mytree->PreOrder(mytree->root);
cout<<endl;
cout<<"In PostOrder"<<endl;
mytree->PostOrder(mytree->root);
cout<<endl;
}
  • 在使用

    之前未能实例化ExpressionTree
    ExpressionTree* mytree = new ExpressionTree(); // THIS!
    mytree->create();
    
  • 打印评估值失败

    cout<<"The Answer is: "<<endl;
    cout << mytree->Evaluate(mytree->root); // THIS!
    
  • 您未能处理Evaluate中的叶节点

    int ExpressionTree::Evaluate(TreeNode *n) { //Evaluates tree
        switch(n->operation) { //switch statement to decide what operator is being used
            case '+': return (Evaluate(n->left) + Evaluate(n->right));
            case '-': return (Evaluate(n->left) - Evaluate(n->right));
            case '*': return (Evaluate(n->left) * Evaluate(n->right));
            case '/': return (Evaluate(n->left) / Evaluate(n->right));
        }
        return n->data; // THIS!
    }
    

现在你只剩下大量的内存管理地狱,和一个相当无用的树表示(除非你实现,例如一个解析器返回一个)。

另外,在TreeNode元素上有许多容易出错的不变量,Evaluate可以是treenode的虚成员,并且可以有虚的、一元的和二值的表达式树节点(虚的表示值)。

这是一个删除了内存管理错误的版本(保留异常安全作为练习):Live On Coliru

#include <iostream>
#include <string>
using namespace std;

class TreeNode {                            //Leaf Node
    TreeNode(TreeNode const&);            // no copy
    TreeNode& operator=(TreeNode const&); // no copy
public:
    TreeNode(char operation, int data, TreeNode* p)
      : left(0), right(0), parent(p),
        operation(operation), data(data)
    { //constructor
    }
    ~TreeNode() {
        delete left;
        delete right;
        left = right = 0;
    }
    TreeNode* left;
    TreeNode* right;
    TreeNode* parent;
    char operation;
    int data;
};
class ExpressionTree {              //expression tree
    ExpressionTree(ExpressionTree const&);            // no copy
    ExpressionTree& operator=(ExpressionTree const&); // no copy
public:
    ExpressionTree() : root(0) {}
    void create();                  //creates binary expression tree
    TreeNode* root;                //instance of TreeNode
    int Evaluate(TreeNode * n);     //evaluates tree
    void InOrder(TreeNode * n);     //traverses tree InOrder
    void PreOrder(TreeNode *n);     //traverses tree PreOrder
    void PostOrder(TreeNode *n);    //traverses tree PostOrder
    ~ExpressionTree()
    {
        delete root;
        root = 0;
    }
};
void ExpressionTree::create() {     //creates binary expression tree
    root              = new TreeNode('*', 3, 0);
    root->left        = new TreeNode('+', 5, root);
    root->left->left  = new TreeNode('2', 2, root->left);
    root->left->right = new TreeNode('3', 3, root->left);
    root->right       = new TreeNode('5', 5, root);
}
int ExpressionTree::Evaluate(TreeNode *n) { //Evaluates tree
    switch(n->operation) { //switch statement to decide what operator is being used
        case '+': return (Evaluate(n->left) + Evaluate(n->right));
        case '-': return (Evaluate(n->left) - Evaluate(n->right));
        case '*': return (Evaluate(n->left) * Evaluate(n->right));
        case '/': return (Evaluate(n->left) / Evaluate(n->right));
    }
    return n->data;
}
void ExpressionTree::InOrder(TreeNode * n) { //traverses the tree InOrder
    if(n) {
        InOrder(n->left);
        cout << n->operation << " ";
        InOrder(n->right);
    }
}
void ExpressionTree::PreOrder(TreeNode * n) { //traverses the tree PreOrder
    if(n) {
        cout << n->operation << " ";
        PreOrder(n->left);
        PreOrder(n->right);
    }
}
void ExpressionTree::PostOrder(TreeNode * n) { //traverses the tree PostOrder
    if(n) {
        PostOrder(n->left);
        PostOrder(n->right);
        cout << n->operation << " ";
    }
}
int main() {                                //main program
    ExpressionTree* mytree = new ExpressionTree();
    mytree->create();
    cout<<"The Answer is: "<<endl;
    cout << mytree->Evaluate(mytree->root);
    cout<<endl;
    cout<<"In InOrder"<<endl;
    mytree->InOrder(mytree->root);
    cout<<endl;
    cout<<"In PreOrder"<<endl;
    mytree->PreOrder(mytree->root);
    cout<<endl;
    cout<<"In PostOrder"<<endl;
    mytree->PostOrder(mytree->root);
    cout<<endl;
    delete mytree;
}