| CIS 330 Home Page | Last updated 2008/02/08 11:09:36 |
The first two problems use the class Array, which implements a simple single dimensional array of integers, encapsulating the memory allocation, copy initialization, assignment, and array operations. Array is used as a base class in the first two problems. The code for class Array can be found in Array.h.
Your class RangeArray must inherit from Array and use as much of the functionality of Array as possible. Implement RangeArray in a single header file RangeArray.h which includes the supplied Array.h. You do not need to change Array.h or submit it, but your RangeArray.h must include it.
Use the driver code rarrayTest.c to test your solution.
Running this program should produce the following:
a1 is [3 5 7 9 11 13 15 17 19 21] a2 is [3 5 7 9 11 13 15 17 19 21] a3 is [2 5 8 11 14] a2 is [2 5 8 11 14] r1 is [1 2 3 4 5 6 7 8 9 10 11 12] r2 is [23 22 21 20 19 18 17 16 15 14] r3 is [1 2 3 4 5 6 7 8 9 10 11 12] r3 is [23 22 21 20 19 18 -7 16 15 14] a2 is [23 22 21 20 19 18 -7 16 15 14]
Your class GrowableArray must inherit from Array and use as much of the functionality of Array as possible. Implement GrowableArray in a single header file GrowableArray.h which includes the supplied Array.h. You do not need to change Array.h or submit it, but your GrowableArray.h must include it.
Use the driver code garrayTest.c to test your solution.
Running this program should produce the following:
g is [3 5 7 9 11 13 15 17 19 21] g2 is [3 5 7 9 11 13 15 17 19 21 0 0 0 13 0 0 0 0 0 0]
You may have various abstract classes in your inheritance hierarchy, but must at least define the abstract base class Expr from which all of your other classes directly or indirectly derive. You may find it useful to define intermediate abstract classes such as BinaryExpr or UnaryExpr to maximize code reuse.
Each of your classes must have the method evaluate to evaluate the expression. Evaluate returns a C++ bool value, the truth value of the expression. The constructors of your classes should behave as shown in the driver code, allowing an expression tree to be built and evaluated. Moreover, your classes must also implement a mechanism for printing using iostream operators.
The idea of this expression hierarchy is to be able to create expression trees and evaluate them dynamically. That is, the evaluate method should not be called by constructors - you should assume that in real use, the evaluation would not be known as the expressions are constructed, but only after construction. This implies that the various expression subclasses are likely to contain pointers or references to the expression objects that they are made from.
Implement all of your classes in a single header file Expr.h.
Use the driver code exprTest.c to test your solution. Note that the driver code defines another class, Query which derives from Expr. This class simulates the notion of a database query (and simulates the evaluation by choosing a random result value). The driver then forms various Boolean expressions of the queries and evaluates them.
Running this program produces results like the following:
Query1 is false
Query2 is true
Query3 is false
( Query1 ) AND ( Query2 ) is false
( Query1 ) OR ( Query2 ) is true
( ( Query1 ) OR ( Query2 ) ) AND ( Query3 ) is false
NOT ( ( ( ( Query1 ) AND ( Query2 ) ) AND ( ( Query1 )
OR ( Query2 ) ) ) OR ( NOT ( ( ( Query1 ) OR ( Query2 ) )
AND ( Query3 ) ) ) ) is false
( ( Query1 ) XOR ( Query2 ) ) XOR ( Query3 ) is true
The next to last line of output has been spread over three lines for
this web page, but your program should produce it as one single line.
Note: the example Query class in the driver has a clone method. Since we want to be able to create expression objects from other temporary expression objects (as in the variable e4, the temporary objects must be able to be cloned so that they persist after the temporary disappears. (And the object creating the clone will be responsible for cleanup.)