I need help doing a simple part of a project. I need help implementing a menu fo
ID: 3597188 • Letter: I
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 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<String> implements ExpressionTreeInterface<String>{
private HashMap<String, Variable> variables;
private String[] postfix;
public ExpressionTree(String[] args) {
variables = new HashMap<String, Variable>();
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<String> 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<String> postfixToExpressionTree(String[] postfix){
Stack<BinaryTree<String>> stack = new Stack<BinaryTree<String>>();
for(String token : postfix) {
if(isVariable(token) || isDouble(token)) {
stack.push(new BinaryTree<String>(token));
continue;
}else if(!isOperator(token) && !isVariable(token) && !isDouble(token)) {
throw new IllegalArgumentException("Variable must be defined.");
}
else if(isOperator(token)) {
BinaryTree<String> right = stack.pop();
BinaryTree<String> left = stack.pop();
stack.push(new BinaryTree<String>(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<String> it = postfixToExpressionTree(postfix).getPostorderIterator();
while(it.hasNext()) {
post += it.next();
if(it.hasNext()) {
post += " ";
}
}
System.out.println(post);
}
}
ExpressionTreeInterface.java
public interface ExpressionTreeInterface<T> extends BinaryTreeInterface<String> {
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<T> {
private T data;
private BinaryNode<T> leftChild, rightChild;
public BinaryNode() {
this(null);
}
public BinaryNode(T data) {
this(data, null, null);
}
public BinaryNode(T data, BinaryNode<T> left, BinaryNode<T> right) {
this.data = data;
leftChild = left;
setRightChild(right);
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public BinaryNode<T> getLeftChild(){
return leftChild;
}
public void setLeftChild(BinaryNode<T> left) {
leftChild = left;
}
public BinaryNode<T> getRightChild() {
return rightChild;
}
public void setRightChild(BinaryNode<T> right) {
this.rightChild = right;
}
public boolean hasLeftChild() {
return leftChild != null;
}
public boolean hasRightChild() {
return rightChild != null;
}
public boolean isLeaf() {
return (!hasLeftChild() && !hasRightChild());
}
public BinaryNode<T> copy(){
BinaryNode<T> newRoot = new BinaryNode<T>(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<T> 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<T> 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<T> implements BinaryTreeInterface<T> {
private BinaryNode<T> root;
public BinaryTree() {
root = null;
}
public BinaryTree(T rootData) {
root = new BinaryNode<T>(rootData);
}
public BinaryTree(T rootData, BinaryTree<T> leftTree, BinaryTree<T> rightTree) {
privateSetTree(rootData, leftTree, rightTree);
}
public void setTree(T rootData) {
root = new BinaryNode<T>(rootData);
}
public void setTree(T rootData, BinaryTree<T> left, BinaryTree<T> right) {
privateSetTree(rootData, left, right);
}
private void privateSetTree(T rootData, BinaryTree<T> left, BinaryTree<T> 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<T> getRootNode() {
return root;
}
public Iterator<T> getPreorderIterator() {
throw new UnsupportedOperationException("Preorder not supported.");
}
public Iterator<T> getInorderIterator() {
throw new UnsupportedOperationException("Inorder not supported.");
}
public Iterator<T> getPostorderIterator() {
return new PostorderIterator();
}
public Iterator<T> getLevelorderIterator() {
throw new UnsupportedOperationException("Level Order not supported.");
}
private class PostorderIterator implements Iterator<T> {
private Stack<BinaryNode<T>> nodeStack;
private BinaryNode<T> current;
public PostorderIterator() {
nodeStack = new Stack<>();
current = root;
populateStack(current);
}
private void populateStack(BinaryNode<T> 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<T> extends TreeInterface<T>, TreeIteratorInterface<T>{
public void setTree(T rootData);
public void setTree(T rootData, BinaryTree<T> left, BinaryTree<T> right);
}
TreeIteratorInterface.java
import java.util.Iterator;
public interface TreeIteratorInterface<T> {
public Iterator<T> getPreorderIterator();
public Iterator<T> getInorderIterator();
public Iterator<T> getPostorderIterator();
public Iterator<T> getLevelorderIterator();
}
TreeInterface.java
public interface TreeInterface<T> {
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.
Explanation / Answer
I found a bug in your code. If Scanner object used to read a string using nextLine method after that it can't be used to read integer. So you have to use one more scanner object to read strings, which I've done in the below code. Please observe the changes. Comment if you need any other help. Thank you..
code:
import java.util.Scanner;
import java.util.StringTokenizer;
public class ExpressionTest {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
Scanner kb1 = new Scanner(System.in);
boolean quit = true;
//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 = kb1.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 = kb1.nextLine();
System.out.print(" Variable value: ");
double value = kb.nextDouble();
//exp.setVariable(name, value);
break;
case 3:
System.out.println("Case 333333");//Remove this line
break;
case 4:
System.out.println("Case 333333");//Remove this line
break;
case 5:
quit = false;
break;
default:
System.out.println("Enter Correct option..");
break;
}
}
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.