简体   繁体   中英

evaluate expression binary tree c++

I was trying to learn this implementation of a binary tree that evaluates an expression. I was unable to run it and see the output. How would i get 3*(7+1)/4+(17-5), which results in 18. Here is the link http://math.hws.edu/eck/cs225/s03/binary_trees/

class ExpNode {
          // Represents a node of any type in an expression tree.
          // This is an "abstract" class, since it contains an undefined
          // function, value(), that must be defined in subclasses.
          // The word "virtual" says that the defintion can change
          // in a subclass.  The "= 0" says that this function has
          // no definition in this class.

     public:     

       virtual double value() = 0;  // Return the value of this node.

   }; // end class ExpNode


class ConstNode : public ExpNode {
          // Represents a node that holds a number.  (The
          // ": public ExpNode" says that this class is
          // a subclass of ExpNode.)

       double number;  // The number in the node.

     public:

       ConstNode( double val ) {
             // Constructor.  Create a node to hold val.
          number = val;
       }

       double value() {
             // The value is just the number that the node holds.
          return number;
       }

    }; // end class ConstNode


class BinOpNode : public ExpNode {
          // Represents a node that holds an operator.

       char op;        // The operator.
       ExpNode *left;   // The left operand.
       ExpNode *right;  // The right operand.

     public:

       BinOpNode( char op, ExpNode *left, ExpNode *right ) {
             // Constructor.  Create a node to hold the given data.
          this->op = op;
          this->left = left;
          this->right = right;
       }

       double value() {
             // To get the value, compute the value of the left and
             // right operands, and combine them with the operator.
           double leftVal = left->value();
           double rightVal = right->value();
           switch ( op ) {
               case '+':  return leftVal + rightVal;
               case '-':  return leftVal - rightVal;
               case '*':  return leftVal * rightVal;
               case '/':  return leftVal / rightVal;
            }
       }

    }; // end class BinOpNode

Here is my attempt to make a main function:

int main() {
    BinOpNode *opnode;
    opnode = new BinOpNode;
    opnode->value()=5;
    ExpNode *expnode;
    expnode = opnode;
    expnode->value();
    return 0;

}

It does not compile, this is the errors

15:58:27 **** Incremental Build of configuration Debug for project ExpNode ****
Info: Internal Builder is used for build
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\ExpNode.o" "..\\src\\ExpNode.cpp" 
..\src\ExpNode.cpp: In function 'int main()':
..\src\ExpNode.cpp:60:15: error: no matching function for call to 'BinOpNode::BinOpNode()'
..\src\ExpNode.cpp:36:2: note: candidates are: BinOpNode::BinOpNode(char, ExpNode*, ExpNode*)
..\src\ExpNode.cpp:30:33: note:                 BinOpNode::BinOpNode(const BinOpNode&)
..\src\ExpNode.cpp:61:18: error: lvalue required as left operand of assignment

15:58:28 Build Finished (took 405ms)

None of the classes have default constructors.
value returns the result of evaluating the expression, and you need to pass the necessary parts of an expression as its parameters when it's constructed.
(It's unclear how you would expect to be able to assign the value 5 to a binary expression.)

You need to build a tree from the leaves (which will be constants) up towards the root.
As an example, here's the expression 5 + 3 :

ConstNode five(5);
ConstNode three(3);
BinOpNode fiveplusthree('+', &five, &three);
std::cout << fiveplusthree.value(); // Should print 8

I think the problem is in your main() function's logic.

According to the definition of the given classes, first you should create an object of type ConstNode for each number in the expression. Then, you should create BinOpNode for each operator in the expression.

And by the way, that expression evaluates to 18, not 82!

Something like this:

//3*(7+1)/4+(17-5)  = 18
int main()
{
  BinOpNode *a, *b;
  a = new BinOpNode('+', new ConstNode(7), new ConstNode(1));
  a = new BinOpNode('*', new ConstNode(3), a);
  a = new BinOpNode('/', a, new ConstNode(4));
  b = new BinOpNode('-', new ConstNode(17), new ConstNode(5));
  b = new BinOpNode('+', a, b);
  cout << b->value();
}

PS: We can pass an object of class ConstNode when an object of ExpNode is expected in the constructor of BinOpNode as ConstNode inherits from ExpNode abstract base class.

In C++, default constructors work interestingly.

If you don't define any constructors, a default constructor is generated for you:

class A {};

int main()
{
    A a; // perfectly fine

But if you define any other constructor, those generated constructors go away:

class A
{
    A(int) { ... }
};

int main()
{
    A a; // ERROR!
}

In this scenario, the default constructor doesn't exist because you defined one, and the compiler didn't generate one for you.

This is your problem because here in main , you have this line:

opnode = new BinOpNode;

which runs the default constructor of BinOpNode . Look at your BinOpNode constructors:

BinOpNode( char op, ExpNode *left, ExpNode *right )

Hey look: thats not a default constructor!

You have two options: either add a default constructor to the class:

BinOpNode() { ... }

or use the arguments when calling new :

opnode = new BinOpNode(op, left, right);

Good Luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM