Question: I need help doing a simple part of a project. I need help implementing a menu for a user to input an expression into my
I need help doing a simple part of a project. I need help implementing a menu for a user to input an expression into my expression tree program. The user should be able to enter an expression in the form of a string seperated by spaces, and that string input should then be transformed into a string array with every part seperated by spaces being an element in the expression. Here is the source code: (further clarifications will follow it). I only want changes made to ExpressionTest, the program is funtional I just don't know how to implement this menu.
ExpressionTree.java
//
import java.util.HashMap; import java.util.Iterator; import java.util.Stack;
public class ExpressionTree extends BinaryTree implements ExpressionTreeInterface{ private HashMap variables; private String[] postfix; public ExpressionTree(String[] args) { variables = new HashMap(); postfix = args; } public double evaluate() { return evaluate(postfixToExpressionTree(postfix).getRootNode()); } public void setVariable(String str, double d){ variables.put(str, new Variable(str, d)); } private double evaluate(BinaryNode rootNode) { double result; if(rootNode == null) { result = 0; }else if(rootNode.isLeaf()) { String root = rootNode.getData(); if(isVariable(root)) result = variables.get(root).getValue(); else result = Double.parseDouble(root); }else { double firstOp = evaluate(rootNode.getLeftChild()); double secondOp = evaluate(rootNode.getRightChild()); String operator = rootNode.getData(); result = compute(operator, firstOp, secondOp); } return result; } private double compute(String operator, double first, double second){ switch(operator) { case "+": return first + second; case "-": return first - second; case "*": return first * second; case "/": if (second == 0) throw new ArithmeticException("Cannot divide by zero"); return first / second; } return 0; } private BinaryTree postfixToExpressionTree(String[] postfix){ Stack> stack = new Stack>(); for(String token : postfix) { if(isVariable(token) || isDouble(token)) { stack.push(new BinaryTree(token)); continue; }else if(!isOperator(token) && !isVariable(token) && !isDouble(token)) { throw new IllegalArgumentException("Variable must be defined."); } else if(isOperator(token)) { BinaryTree right = stack.pop(); BinaryTree left = stack.pop(); stack.push(new BinaryTree(token, left, right)); } } return stack.pop(); } private boolean isDouble(String str) { try { Double.parseDouble(str); return true; }catch(NumberFormatException e) { return false; } } private boolean isVariable(String str) { return variables.containsKey(str); } private boolean isOperator(String str) { switch(str) { case "+": case "-": case "*": case "/": return true; } return false; } public void displayPostfix() { String post = ""; Iterator it = postfixToExpressionTree(postfix).getPostorderIterator(); while(it.hasNext()) { post += it.next(); if(it.hasNext()) { post += " "; } } System.out.println(post); } }
ExpressionTreeInterface.java
public interface ExpressionTreeInterface extends BinaryTreeInterface { public double evaluate(); }
Variable.java
public class Variable { private String name; private double value; public Variable(String name) { this.name = name; } public Variable(String name, double value) { this.name = name; this.setValue(value); } public String getName() { return name; } public void setName(String newName) { this.name = newName; }
public double getValue() { return value; }
public void setValue(double value) { this.value = value; } }
BinaryNode.java
public class BinaryNode { private T data; private BinaryNode leftChild, rightChild; public BinaryNode() { this(null); } public BinaryNode(T data) { this(data, null, null); } public BinaryNode(T data, BinaryNode left, BinaryNode right) { this.data = data; leftChild = left; setRightChild(right); } public T getData() { return data; } public void setData(T data) { this.data = data; } public BinaryNode getLeftChild(){ return leftChild; } public void setLeftChild(BinaryNode left) { leftChild = left; }
public BinaryNode getRightChild() { return rightChild; }
public void setRightChild(BinaryNode right) { this.rightChild = right; } public boolean hasLeftChild() { return leftChild != null; } public boolean hasRightChild() { return rightChild != null; } public boolean isLeaf() { return (!hasLeftChild() && !hasRightChild()); } public BinaryNode copy(){ BinaryNode newRoot = new BinaryNode(data); if(leftChild != null) { newRoot.setLeftChild(leftChild.copy()); } if(rightChild != null) { newRoot.setRightChild(rightChild.copy()); } return newRoot; } public int getHeight() { return getHeight(this); } private int getHeight(BinaryNode node) { int height = 0; if(node != null) { height = 1 + Math.max(getHeight(node.getLeftChild()), getHeight(node.getRightChild())); } return height; } public int getNumberOfNodes() { return getNumberOfNodes(this); } private int getNumberOfNodes(BinaryNode node) { int rightNumber = 0; int leftNumber = 0; if(leftChild != null) { leftNumber = getNumberOfNodes(node.getLeftChild()); } if(rightChild != null) { rightNumber = getNumberOfNodes(node.getRightChild()); } return 1 + leftNumber + rightNumber; } }
BinaryTree.java
import java.util.Iterator; import java.util.Stack;
public class BinaryTree implements BinaryTreeInterface {
private BinaryNode root;
public BinaryTree() { root = null; }
public BinaryTree(T rootData) { root = new BinaryNode(rootData); }
public BinaryTree(T rootData, BinaryTree leftTree, BinaryTree rightTree) { privateSetTree(rootData, leftTree, rightTree); }
public void setTree(T rootData) { root = new BinaryNode(rootData); }
public void setTree(T rootData, BinaryTree left, BinaryTree right) { privateSetTree(rootData, left, right); }
private void privateSetTree(T rootData, BinaryTree left, BinaryTree right) { root = new BinaryNode<>(rootData);
if ((left != null) && (!left.isEmpty())) { root.setLeftChild(left.root.copy()); } if ((right != null) && (!right.isEmpty())) { root.setRightChild(right.root.copy()); } }
public T getRootData() { return root.getData(); }
public int getHeight() { return root.getHeight(); }
public int getNumberOfNodes() { return root.getNumberOfNodes(); }
public boolean isEmpty() { return root == null; }
public void clear() { root = null; }
protected BinaryNode getRootNode() { return root; }
public Iterator getPreorderIterator() { throw new UnsupportedOperationException("Preorder not supported."); }
public Iterator getInorderIterator() { throw new UnsupportedOperationException("Inorder not supported."); }
public Iterator getPostorderIterator() { return new PostorderIterator(); }
public Iterator getLevelorderIterator() { throw new UnsupportedOperationException("Level Order not supported."); }
private class PostorderIterator implements Iterator {
private Stack> nodeStack; private BinaryNode current;
public PostorderIterator() { nodeStack = new Stack<>(); current = root; populateStack(current); } private void populateStack(BinaryNode node){ nodeStack.add(node); if(node.hasRightChild()){ populateStack(node.getRightChild()); } if(node.hasLeftChild()){ populateStack(node.getLeftChild()); } }
public boolean hasNext() { return !nodeStack.isEmpty(); }
public T next() { return nodeStack.pop().getData(); }
}
}
BinaryTreeInterface.java
public interface BinaryTreeInterface extends TreeInterface, TreeIteratorInterface{ public void setTree(T rootData); public void setTree(T rootData, BinaryTree left, BinaryTree right); }
TreeIteratorInterface.java
import java.util.Iterator;
public interface TreeIteratorInterface { public Iterator getPreorderIterator(); public Iterator getInorderIterator(); public Iterator getPostorderIterator(); public Iterator getLevelorderIterator(); }
TreeInterface.java
public interface TreeInterface { public T getRootData(); public int getHeight(); public int getNumberOfNodes(); public boolean isEmpty(); public void clear(); }
ExpressionTest.java
package TreePackage;
import java.util.Scanner;
import java.util.StringTokenizer;
public class ExpressionTest {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
boolean quit = false;
ExpressionTree exp = new ExpressionTree(new String[]{"a", "b", "2", "/","+"});
while(!quit){
System.out.println("J. Botkin's Expression Tree "
+ "1. Enter New Expression "
+ "2. Set Expression Variables "
+ "3. Evaluate Expression "
+ "4. Display Postfix "
+ "5. Quit");
int option = kb.nextInt();
switch (option) {
case 1:
System.out.println("Enter Expression seperated by spaces.");
String userInput = kb.nextLine();
String[] userExp = userInput.split(" ");
StringTokenizer toToken = new StringTokenizer(userInput, " ");
exp = new ExpressionTree(new String[]{userExp[0], userExp[1], userExp[2], userExp[3],userExp[4]});
break;
case 2:
System.out.print("Variable name: ");
String name = kb.nextLine();
System.out.print(" Variable value: ");
double value = kb.nextDouble();
exp.setVariable(name, value);
break;
case 3:
System.out.println(exp.evaluate());
break;
case 4:
exp.displayPostfix();
break;
case 5:
quit = true;
break;
default:
System.out.println("Enter Correct option.");
break;
}
/* ExpressionTree exp = new ExpressionTree(new String[]{"a", "b", "2", "/","+"});
exp.setVariable("z", 1.5);
exp.setVariable("b", 3);
exp.setVariable("a", 2);
System.out.println(exp.evaluate());
exp.displayPostfix(); */
}
}
}
The commented out section at the end of ExpressionTest displays how these methods funtion, I just need this menu to work and the user to be able to enter an expression.