Computer Science Department
For this assignment, you will convert an arithmetic expression, like ( 3 + 4.5 ) * 2 given as a String, into a binary tree representation. You will use the binary tree to print the expression as a prefix, infix, and postfix expression by traversing the tree in pre-order, in-order, and post-order, respectively. You will also use the tree to evaluate the expression.
Expressions will only contain the binary operators +, -, *, and /. No unary
operators, like - 2, are allowed. Numbers can be
any valid double. If an expression
includes parentheses, the parentheses must be separated by a space from
other tokens. This will allow you to use StringTokenizer to
extract each item from the String expression. Also, assume that the
expression does not include any redundant parentheses. In other words,
expressions like 3.2 + ( ( 2 * 4 ) ) and 64 - ( 2 / 3 ( ) ) are not legal.
Your program does not have to handle these illegal expressions.
Write your program so that the expression is given as a command line argument. Given this String, your program must do the following steps:
-> java main "3 + 5.5" --------New Expression--------- 3 + 5.5 Preorder: + 3.0 5.5 Postorder: 3.0 5.5 + Inorder: 3.0 + 5.5 Evaluation: 8.5 ->
You can write a simple shell script to test a number of expressions.
For example, if I create a file named testexp with the
following lines:
java main "4.1 + 3" java main "4.1 - 3" java main "4.1 * 3" java main "4.1 / 3" java main "3 + 4 * 2" java main "3 + ( 4 * 2 )" java main "3 + ( ( 12.5 / 6.7 ) + ( 4 * 2 ) )" java main "3 + ( 5 - 6 ) * ( 50 - 2 / 2 )"and then make it executable by doing
chmod a+x testexpand then running it by typing
testexpI get the following output.
--------New Expression---------
4.1 + 3
Preorder: + 4.1 3.0
Postorder: 4.1 3.0 +
Inorder: 4.1 + 3.0
Evaluation: 7.1
--------New Expression---------
4.1 - 3
Preorder: - 4.1 3.0
Postorder: 4.1 3.0 -
Inorder: 4.1 - 3.0
Evaluation: 1.0999999999999996
--------New Expression---------
4.1 * 3
Preorder: * 4.1 3.0
Postorder: 4.1 3.0 *
Inorder: 4.1 * 3.0
Evaluation: 12.299999999999999
--------New Expression---------
4.1 / 3
Preorder: / 4.1 3.0
Postorder: 4.1 3.0 /
Inorder: 4.1 / 3.0
Evaluation: 1.3666666666666665
--------New Expression---------
3 + 4 * 2
Preorder: * + 3.0 4.0 2.0
Postorder: 3.0 4.0 + 2.0 *
Inorder: 3.0 + 4.0 * 2.0
Evaluation: 14.0
--------New Expression---------
3 + ( 4 * 2 )
Preorder: + 3.0 * 4.0 2.0
Postorder: 3.0 4.0 2.0 * +
Inorder: 3.0 + 4.0 * 2.0
Evaluation: 11.0
--------New Expression---------
3 + ( ( 12.5 / 6.7 ) + ( 4 * 2 ) )
Preorder: + 3.0 + / 12.5 6.7 * 4.0 2.0
Postorder: 3.0 12.5 6.7 / 4.0 2.0 * + +
Inorder: 3.0 + 12.5 / 6.7 + 4.0 * 2.0
Evaluation: 12.865671641791044
--------New Expression---------
3 + ( 5 - 6 ) * ( 50 - 2 / 2 )
Expression tree:
2.0
/
2.0
-
50.0
*
6.0
-
5.0
+
3.0
Preorder: * + 3.0 - 5.0 6.0 / - 50.0 2.0 2.0
Postorder: 3.0 5.0 6.0 - + 50.0 2.0 - 2.0 / *
Inorder: 3.0 + 5.0 - 6.0 * 50.0 - 2.0 / 2.0
Evaluation: 48.0
This part of the problem is usually referred to as
First, let's define a method that is called to start converting the
string into a binary tree. It will also be used to build a subtree
for any expression that is surrounded by parentheses. Use a
StringTokenizer object to keep track of the remaining
unconverted expression. So, this method
must receive as arguments the StringTokenizer object and
a String that tells the method when to stop converting.
If it is being used to convert just an expression between ( and ),
then the second argument should be ")". The first time it is
called, the second argument should be null, indicating
that the method should continue to convert the expression until no
more tokens are available. Let's call this method
buildExpTree. It calls another method, buildTerm,
defined below. Here are the steps that buildExpTree should
follow:
buildTerm to convert the left term into a
binary tree.
buildTerm to convert the right term of this
operator into a binary tree.
buildTerm to create either a leaf node
containing a number or a subtree representing a parenthesized
expression. buildTerm just needs the
StringTokenizer as an argument, and it follows these
steps:
buildExpTree with the StringTokenizer and
")" as the string to stop at.
You already know how to traverse a binary tree. As discussed in class, the body for each traversal method will only require about four lines. Do not write general traversal methods---just write specific ones that simply print the value of node passed in as an argument and, of course, recurse on the left and right children.
To print the side-ways diagram of the tree, traverse the tree in-order, but
swap the order of visiting the right and left children. Pass a second
argument to this method that is an int whose value is the
depth of the node passed in as the first argument. Use the depth to decide
how many spaces to print before printing the value of the node.
The result will be a tree that looks correct when you turn your paper 1/4 turn
clockwise.
For example, the diagram below on the left is what you will print. It
represents the tree on the right:
3 +
* / \
6.4 3.4 *
+ / \
3.4 6.4 3
You will end up with a total of four traversal methods, three to simply print the pre, in, and post-order expression, and one to print the diagram.
Now that the expression is represented as a binary tree, it is extremely easy to evaluate using a recursive method. Simply evaluate the left child and the right child of the root node, then combine the results using the operator stored in the root node.
This recursive method must first check to see if the left child of the node passed in as an argument is not null. If the left child is null, then it simply returns the double value of the argument.
In addition to the main class, you will need a class to define
a binary tree node. Do not define a complete BinaryTree class like the one in
the text book, just define the class for a binary tree node. Include this
as an inner class in your
main.java file.
All other methods you are writing will be methods in the main class.
This way you will end up with a single java file.
Since you are developing a single Java file, you will have to be creative in dividing this problem among your team members and testing each part. Converting the String expression into a binary tree will be the hardest part. While one or two work on that part, the others could write some temporary code to build a simple binary tree that can be passed to the traversal methods to test them. A hand-coded valid expression tree can be be passed to the evaluation method to test it.
Make heavy use of the traversal method that prints the tree diagram. This can be used to print a diagram of the whole tree or any subtree. You can observe the construction of your expression tree by sprinkling calls to your diagram method within the construction code.
Electronically check in one file, Main.java, using a file
appendage of .p
See the Checkin documentation to check in your files if you need to.
Copyright © 1997, 1998, 1999: Colorado State University for CS200. All rights reserved.