I'm pretty lost at the moment on how I would go about implementing this Tree, I'm trying to construct a Tree from a string representation of input "(4 + 6) + (2 + 3)". How would I go about making a Tree from two Stacks?
public class Tree {
private Stack opStk = new Stack();
private Stack valStk = new Stack();
private Tree parent = null;
public Tree(String str){
System.out.println((EvaluateExpression(str)));
}
public void doOperation() {
Object x = valStk.pop();
Object y = valStk.pop();
Object op = opStk.pop();
if ((Integer) x <= 0 || (Integer) y <= 0){
throw new NumberFormatException();
}
if (op.equals("+")) {
int sum = (Integer) x + (Integer) y;
valStk.push(sum);
}
}
public void repeatOps(char refOp) {
while (valStk.count() > 1 &&
prec(refOp) <= prec((char)opStk.pop())) {
doOperation();
}
}
int prec(char op) {
switch (op) {
case '+':
case '-':
return 0;
case '*':
case '/':
return 1;
case '^':
return 2;
default:
throw new IllegalArgumentException("Operator unknown: " + op);
}
}
public Object EvaluateExpression(String str) {
System.out.println("Evaluating " + str);
Scanner s = null;
try {
s = new Scanner(str);
//while there is tokens to be read
while (s.hasNext()) {
//if token is an int
if (s.hasNextInt()) {
//read it
int val = s.nextInt();
if(val <= 0) {
throw new NumberFormatException("Non-positive");
}
System.out.println("Val " + val);
//push it to the stack
valStk.push(val);
} else {
//push operator
String next = s.next();
char chr = next.charAt(0);
System.out.println("Repeat Ops " + chr);
repeatOps(chr);
System.out.println("Op " + next);
opStk.push(chr);
}
repeatOps('+');
}
} finally {
if (s != null) {
s.close();
}
}
System.out.println("Should be the result: " + valStk.pop());
return valStk.pop();
}
I have a few suggestions to make that might set you on the right path (hopefully).
Firstly I suggest your expression tree follow the Composite Design Pattern. It works very well for these types of hierarchies. For your purpose it would look something like:
interface Expression {
int getValue();
}
class Constant implements Expression {
private int value;
public int getValue() {
return value;
}
}
class Operation implements Expression {
private Expression operand1;
private Operator operator;
private Expression operand2;
public int getValue() {
return operator.apply(operand1, operand2);
}
}
Note that you don't need any concept of operator precedence or parentheses: it's entirely implicit in how the tree is constructed. For example "3 + 4 * 2" should result in a tree "(+ 3 (* 4 2))" while "(3 + 4) * 2" should result in a tree "(* (+ 3 4) 2)".
Secondly I suggest you make your operators into an enum rather than relying on the string values:
enum Operator {
TIMES((n1, n2) -> n1 * n2),
DIVIDE((n1, n2) -> n1 / n2),
PLUS((n1, n2) -> n1 + n2),
MINUS((n1, n2) -> n1 - n2);
private final BinaryOperator<Integer> operation;
Operator(BinaryOperator<Integer> operation) {
this.operation = operation;
}
public int apply(int operand1, int operand2) {
return operation.apply(operand1, operand2);
}
}
The advantage of this approach is that it's trivial to add new operators without changing the structure of the tree at all.
Thirdly I suggest you split your conversion from string to expression tree into two steps. The first is to convert from string to tokens and the second from token to trees. These are call lexical and semantic analysis in the jargon.
If you are using the shunting yard algorithm for the semantic analysis then keep in mind that the output stack will hold Expression instances ready to become operands. I can give you more detail on how to shunt operators but it's probably worth you giving the suggestions above a try first.
Related
I am supposed to write a recursive method for generating an expression in an expression tree. The method should have a parameter that limits the "height" of the expression tree. The maxHeight gives the maximum allowable height, not the actual height. The nodes for constants, variables, and binary operators have already been created but I am having issues getting the method to work. Below is the method that I have created and one of the tree nodes. I am still learning Java so please be kind. Any help will be appreciated.
static ExpNode randomExpression(int maxHeight) {
ExpNode e1 = new BinOpNode('+', new VariableNode(), new ConstNode(maxHeight));
ExpNode e2 = new BinOpNode('*', new ConstNode(maxHeight), new VariableNode());
ExpNode e3 = new BinOpNode('*', e1, e2);
ExpNode e4 = new BinOpNode('-', e1, new ConstNode(-3));
if (maxHeight < 0) {
return null;
}
if (maxHeight == 0) {
return new BinOpNode('-', e1, e2);
}
if (maxHeight > 0) {
maxHeight++;
return new BinOpNode('/', e3, e4);
}
return randomExpression(maxHeight);
}
static class BinOpNode extends ExpNode {
char op; // the operator, which must be '+', '-', '*', or '/'
ExpNode left, right; // the expression trees for the left and right operands.
BinOpNode(char op, ExpNode left, ExpNode right) {
if (op != '+' && op != '-' && op != '*' && op != '/')
throw new IllegalArgumentException("'" + op + "' is not a legal operator.");
this.op = op;
this.left = left;
this.right = right;
}
double value(double x) {
double a = left.value(x); // value of the left operand expression tree
double b = right.value(x); // value of the right operand expression tree
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
default: return a / b;
}
}
public String toString() {
return "(" + left.toString() + op + right.toString() + ")";
}
}
}
Im trying to create a recursive parsing calculator in java for addition, multiplication and factorial, but I'm struggling on the very first part of just reading through the user input to split the input into numbers and operators. While debugging I tried to see where it was going wrong, and I found that when the "+" was going through the if else statements it just skipped over it. I'm really unsure on what the issue is, I originally tried using tokens, and splitting up into substring, but it wasn't going well then either. Any help would be appreciated. Thank you
package com.company;
import java.util.Scanner;
class Main {
public static void main(String[] param) {
String input = input("Please enter an expression");
int n = input.length()-1;
String[] splitter = input.split("(?<=\\G.)");
split(input, n);
//int result = calculate(input);
//String[] splitter = input.split("(?<=\\G.)");
}
public static String split(String input, int n) {
String[] splitter = input.split("(?<=\\G.)");
System.out.println(splitter[n]);
String symbol = splitter[n];
if (symbol.equals("+")) {
evalADD(n, splitter);
}
if (symbol.equals("*")) {
evalMULT(n, splitter);
}
if (symbol.equals("!")) {
evalFACT(n, splitter);
}
else if (Integer.parseInt(splitter[n]) >= 0 && Integer.parseInt(splitter[n]) <=9)
{
if (n != 0) {
n = n - 1;
split(input, n);
}
}
if (n != 0)
n = n - 1;
split(input, n);
return input;
}
public static int evalADD(int n, String [] splitter){
int arg1;
int arg2;
int result;
arg1 = Integer.parseInt(splitter[n+1]);
arg2 = Integer.parseInt(splitter[n+2]);
result = arg1 + arg2;
return result;
}
public static int evalMULT(int n, String [] splitter){
int arg1;
int arg2;
int result;
arg1 = Integer.parseInt(splitter[n+1]);
arg2 = Integer.parseInt(splitter[n+2]);
result = arg1 * arg2;
return result;
}
public static int evalFACT(int n, String [] splitter){
int arg1;
int arg2;
int result;
arg1 = Integer.parseInt(splitter[n+1]);
arg2 = Integer.parseInt(splitter[n+2]);
result = arg1 - arg2;
return result;
}
public static String input(String message) {
Scanner scanner = new Scanner(System.in);
System.out.println(message);
return (scanner.nextLine());
}
}
I have noticed that you are using the java.util.Scanner. I wrote a script that should do the task for you by following all of your criteria:
import java.util.Scanner;
class recursiveParsingCalculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Ask user to input the expression
System.out.println("Please input the expression");
String userInput = scanner.nextLine();
System.out.println(
"And the final result is: " + recursiveCalculation(userInput, userInput.length() - 1, 0, 0, 0));
scanner.close();
System.exit(0);
}
// Identify the type of character at a specific position
public static char charOfString(String userInput, int i) {
return userInput.charAt(i);
}
/*
* Position must be userInput.length() - 1 initially. currentResults, operand1
* and operand2 are also meant to be initilized with 0.
*/
public static int recursiveCalculation(String userInput, int position, int operand1, int operand2,
int currentResults) {
// If position is zero, just output the operand.
if (position == 0) {
if (Character.isDigit(charOfString(userInput, position))) {
return charOfString(userInput, position) - '0';
} else {
System.out.println("Invalid input.");
}
}
if (position > -1) {
// Check if it is a number or an operator
if (Character.isDigit(charOfString(userInput, position))) {
operand1 = charOfString(userInput, position) - '0'; // First operand
// Check if 2nd char is a number or an operator.
if (Character.isDigit(charOfString(userInput, position - 1))) {
operand2 = charOfString(userInput, position - 1) - '0';
position = position - 1;
}
} else {
// If it is an operator, then proceed to compute the results so far
char operator = charOfString(userInput, position);
// If it is a binary situation
if (operator == '+' || operator == '*') {
currentResults = binaryOperator(operator, operand1, operand2);
operand2 = currentResults;
}
// If it is an unary situation
else if (operator == '!') {
if (currentResults == 0) {
currentResults = operand1;
}
currentResults = unaryOperator(currentResults);
operand2 = currentResults;
} else {
System.out.println("Invalid operator");
return 0; // Return zero by default
}
}
position = position - 1;
}
if (position > -1) {
return recursiveCalculation(userInput, position, operand1, operand2, currentResults);
} else {
return currentResults;
}
}
public static int binaryOperator(char operator, int operand1, int operand2) {
switch (operator) {
case '+':
return operand1 + operand2;
case '*':
return operand1 * operand2;
default:
System.out.println("Invalid binary Operator");
return 0; // Return zero by default
}
}
// Calculate the factorial
public static int unaryOperator(int operand) {
if (operand <= 1)
return 1;
else
return operand * unaryOperator(operand - 1);
}
}
Examples of usage: For a binary operator, input +21, and it will add them for you. With unary, input !3, and it will yield the factorial. Now, you can try any chain of combinations and permutations of numbers with unary and binary operators, and it will calculate the values for you recursively.
For example, consider the input !*3+12: It will add 1 and 2, then multiply it by 3 and finally, it calculates the factorial out of the whole expression, thereby resulting in 362880 as expected.
Why don't you assign the input calculation string to a character array and iterate through the array and match the characters '+', '-','*'?
I am having problems getting my toString() method to work and print out parenthesis. Within my infix notation. For example, right now if I enter 12+3* it will print out 1 + 2 * 3. I would like it to print out ((1+2) *3).
Also, I would like my expression tree to be built when it contains a space within the input. For example, right now if I enter 12+ it works, but I want to be able to enter 1 2 + and it still work. Any thoughts?
P.S. Ignore my evaluate method I haven't implemented it yet!
// Java program to construct an expression tree
import java.util.EmptyStackException;
import java.util.Scanner;
import java.util.Stack;
import javax.swing.tree.TreeNode;
// Java program for expression tree
class Node {
char ch;
Node left, right;
Node(char item) {
ch = item;
left = right = null;
}
public String toString() {
return (right == null && left == null) ? Character.toString(ch) : "(" + left.toString()+ ch + right.toString() + ")";
}
}
class ExpressionTree {
static boolean isOperator(char c) {
if ( c == '+' ||
c == '-' ||
c == '*' ||
c == '/'
) {
return true;
}
return false;
}
// Utility function to do inorder traversal
public void inorder(Node t) {
if (t != null) {
inorder(t.left);
System.out.print(t.ch + " ");
inorder(t.right);
}
}
// Returns root of constructed tree for given
// postfix expression
Node constructTree(char postfix[]) {
Stack<Node> st = new Stack();
Node t, t1, t2;
for (int i = 0; i < postfix.length; i++) {
// If operand, simply push into stack
if (!isOperator(postfix[i])) {
t = new Node(postfix[i]);
st.push(t);
} else // operator
{
t = new Node(postfix[i]);
// Pop two top nodes
// Store top
t1 = st.pop(); // Remove top
t2 = st.pop();
// make them children
t.right = t1;
t.left = t2;
// System.out.println(t1 + "" + t2);
// Add this subexpression to stack
st.push(t);
}
}
// only element will be root of expression
// tree
t = st.peek();
st.pop();
return t;
}
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
/*boolean keepgoing = true;
while (keepgoing) {
String line = input.nextLine();
if (line.isEmpty()) {
keepgoing = false;
} else {
Double answer = calculate(line);
System.out.println(answer);
}
}*/
ExpressionTree et = new ExpressionTree();
String postfix = input.nextLine();
char[] charArray = postfix.toCharArray();
Node root = et.constructTree(charArray);
System.out.println("infix expression is");
et.inorder(root);
}
public double evaluate(Node ptr)
{
if (ptr.left == null && ptr.right == null)
return toDigit(ptr.ch);
else
{
double result = 0.0;
double left = evaluate(ptr.left);
double right = evaluate(ptr.right);
char operator = ptr.ch;
switch (operator)
{
case '+' : result = left + right; break;
case '-' : result = left - right; break;
case '*' : result = left * right; break;
case '/' : result = left / right; break;
default : result = left + right; break;
}
return result;
}
}
private boolean isDigit(char ch)
{
return ch >= '0' && ch <= '9';
}
private int toDigit(char ch)
{
return ch - '0';
}
}
Why you use inorder()? root.toString() returns exactly what you want, "((1+2)*3)"
Spaces you can skip at start of loop:
for (int i = 0; i < postfix.length; i++) {
if (postfix[i] == ' ')
continue;
...
Change main like this.
Scanner input = new Scanner(System.in);
String postfix = input.nextLine();
char[] charArray = postfix.replace(" ", "").toCharArray();
Node root = constructTree(charArray);
System.out.println("infix expression is");
System.out.println(root);
I have a function that receives a binary expression tree and returns a String with the expression in-order. The only "problem" is that the resulting expression have too many parentheses,
e.g.: The function returns (a + (b * c)), but it can be reduced to a + b * c.
It is defined with the binary operators +, -, *, /, and the unary operator _ (negative).
What I really want to know is if I can modify the already existing function to reduce the number of parentheses in an efficient way, or create another function that operates with the String of the in-order expression.
The function is as follows:
private static String infijo(ArbolB t){
String s = "";
if (t != null) {
String info = String.valueOf(t.info);
if ("+-*/".contains(info)) s += "(";
if ("_".contains(info)) s += "-(";
s += infijo(t.left) + (info.equals("_") ? "" : info) + infijo(t.right);
if ("+-*/_".contains(String.valueOf(t.info))) s += ")";
}
return s;
}
Where ArbolB is a binary tree defined by:
public class ArbolB {
ArbolB right;
ArbolB left;
Object info;
public ArbolB(Object info, ArbolB right, ArbolB left){
this.info = info;
this.right = right;
this.left = left;
}
}
After writing this whole thing out, I realized that I didn't really answer your question properly (my solution ignores PEMDAS and just matches pairs, d'oh!). So, take from this what you can... I'm not throwing it out :P
I think you COULD solve this either way, but here would be my preferred method, using and trusting what you already have. There's probably a good way to use nodes to do this, but why not use what you have, right?
Starting from the point where you have your expression as a string (e.g. "((2*2) + _(3+3))" you could try something like:
public string RemoveUnnecessaryParens(string expression)
{
readonly string openParen = "(";
readonly string closeParen = ")";
// char array would also work for this
// multiple ways to track "balance" of parens, lets use int
int unclosedParenCount = 0;
string toReturn = "";
// iterate through the expression
for (int i = 0; i < expression.Length; i++)
{
string current = expression.Substring(i,1);
if (openParen == current)
unclosedParenCount++;
else if (closedParen == current)
unclosedParenCount--;
else
toReturn += current;
if (unclosedParenCount < 0) throw new UnbalancedExpressionException(); // One more close than open! Uh oh!
}
if (0 != unclosedParenCount) throw new UnbalancedExpressionException(); // One more open than close at the end! Uh oh!
else return toReturn;
}
Make sense?
Well, after thinking it a while, I got to a solution myself, by adding a priority function for determining when parentheses were necessary, and a variable that indicates if the operation was on the left or the right side of the formula, this because a-b+c don't need parentheses, but c+(a-b) do need them.
private static String infijo(ArbolB t, int priority, boolean right) {
String s = "";
int oP = 0;
if (t != null) {
String info = String.valueOf(t.info);
int pi = priority(info);
if ("+-*/".contains(info)) {
/* this only adds parentheses if the operation has higher priority or if the
operation on the right side should be done before the one on the left side*/
if ("+-*/".contains(info)) {
if (pi/2 < priority/2) s += "(";
else s += pi/2 == priority/2 && pi != priority && right ? "(" : "";
oP = priority; //stores the old priority
priority= pi; //priority of the new operator
}
}
if ("_".contains(info)) {
s += "-";
oP = priority;
priority = pi;
}
s += infijo(t.left, priority, false) + (info.equals("_") ? "" : info)
+ infijo(t.right, priority, true);
if ("+-*/".contains(info)) {
// adds the closing parentheses following the same rules as for the opening ones
if (priority / 2 < oP / 2) s += ")";
else s += priority / 2 == oP / 2 && priority != oP && right ? ")" : "";
}
}
return s;
}
private static int priority(String op) {
if ("_".contains(op)) return 4;
if ("/".contains(op)) return 3;
if ("*".contains(op)) return 2;
if ("-".contains(op)) return 1;
return 0;
}
#Override
public String toString() {
ArbolB f = getFormula(); //this returns the Binary Expression Tree
return infijo(f, Integer.MIN_VALUE, false);
}
I'm having trouble implementing a stack as an array in java. When I try to utilize the array, I get nullPointerExceptions. I know that the rest of my code works because I'm able to run the program using the linked list implementation of the stack I have created. The code is below:
Edit: The stack trace is
Exception in thread "main" java.lang.NullPointerException
at LispEvaluator.evaluate(LispEvaluator.java:238)
at LispEvaluator.fileLoader(LispEvaluator.java:67)
at Driver.main(Driver.java:16)
Here is the code for the lispEvaluator class
//code starts here
import java.util.*;
import java.io.*;
public class LispEvaluator {
// Current input Lisp expression
private String inputExpr;
private Scanner sc;
private StackList exprStack;
private StackList tempStack;
// default constructor
// set inputExpr to ""
// create stack objects
public LispEvaluator()
{
inputExpr = "";
}
// default constructor
// set inputExpr to inputExpression
// create stack objects
public LispEvaluator(String inputExpression)
{
inputExpr = inputExpression;
}
// set inputExpr to inputExpression
// clear stack objects
public void reset(String inputExpression)
{
inputExpr = inputExpression;
StackList exprStack=new StackList(50);
StackList tempStack=new StackList(50);
}
private boolean checkifNumber() {
return false;
}
public void fileLoader(String mode,String file){
//Validate the user entered mode
if(mode.equals("0")){
exprStack=new StackList(50);
tempStack=new StackList(50);}
else{
ArrayStack exprStack=new ArrayStack(50);
ArrayStack tempStack=new ArrayStack(50);
}
try{
//Try to read the array from file
sc = new Scanner(new File(file));
while (sc.hasNextLine()) {
double result=0;
inputExpr=sc.nextLine();
reset(inputExpr);
result=evaluate();
System.out.println(result);
}
}
catch (FileNotFoundException e){
System.out.println("Cannot find requested input file");
}
catch(IOException io){
System.out.println("General file io error occured. Try again");
}
}
// This function evaluate current operator with its operands
// See complete algorithm in evaluate()
//
// Main Steps:
// Pop operands from expressionStack and push them onto
// tempStack until you find an operator
// Apply the operator to the operands on tempStack
// Push the result into expressionStack
//
private double add() {
double op1 = (Double) tempStack.pop();
double temp=op1;
while (tempStack.size()>0){
double op2 = (Double) tempStack.pop();
temp = temp + op2;}
return temp;
}
private double multiply() {
double op1 = (Double) tempStack.pop();
double temp=op1;
while (tempStack.size()>0){
double op2 = (Double) tempStack.pop();
temp = temp * op2;}
return temp;
}
private double subtract() {
if (tempStack.size() == 1) {
double temp = -1*(Double) tempStack.pop();
return temp;
} else {
double op1 = (Double) tempStack.pop();
double temp=op1;
while (tempStack.size()>0){
double op2 = (Double) tempStack.pop();
temp = temp - op2;}
return temp;
}
}
private double divide() {
double temp;
if (tempStack.size() == 1) {
temp = 1 / (Double) tempStack.pop();
return temp;
}
else if (tempStack.size() >=1) {
double op1 = (Double) tempStack.pop();
temp=op1;
while (tempStack.size()>0){
double op2 = (Double) tempStack.pop();
temp = temp / op2;}
return temp;
}
return 0;
}
private void evaluateCurrentOperation()
{
while( exprStack.top().getClass().getName().equals("java.lang.Double") ) {
tempStack.push( (Double)exprStack.pop() );
}
Character operator = (Character)exprStack.pop();
Double result = null;
switch( operator ) {
case '+':
result = add();
break;
case '*':
result = multiply();
break;
case '-':
result = subtract();
break;
case '/':
result = divide();
break;
}
exprStack.push( result );
}
/**
* This function evaluates Lisp expression in inputExpr
* It return result of the expression
*
* The algorithm:
*
* Step 1 Scan the tokens in the expression string.
* Step 2 If you see an operand, push operand object onto the expressionStack
* Step 3 If you see "(", next token should be an operator
* Step 4 If you see an operator, push operator object onto the expressionStack
* Step 5 If you see ")" // steps in evaluateCurrentOperation() :
* Step 6 Pop operands and push them onto tempStack
* until you find an operator
* Step 7 Apply the operator to the operands on tempStack
* Step 8 Push the result into expressionStack
* Step 9 If you run out of tokens, the value on the top of expressionStack is
* is the result of the expression.
*/
public double evaluate()
{
// only outline is given...
// you need to add statements
// you may delete or modify any statements in this method
// use scanner to tokenize inputExpr
Scanner inputExprScanner = new Scanner(inputExpr);
// Use zero or more white space as delimiter,
// which breaks the string into single character tokens
inputExprScanner = inputExprScanner.useDelimiter("\\s*");
// Step 1: Scan the tokens in the string.
while (inputExprScanner.hasNext())
{
// Step 2: If you see an operand, push operand object onto the expressionStack
if (inputExprScanner.hasNextInt())
{
// This force scanner to grab all of the digits
// Otherwise, it will just get one char
String dataString = inputExprScanner.findInLine("\\d+");
exprStack.push(new Double(dataString));
// more ...
}
else
{
// Get next token, only one char in string token
String aToken = inputExprScanner.next();
char item = aToken.charAt(0);
String nextToken;
char nextItem;
switch (item)
{
// Step 3: If you see "(", next token should be an operator
case '(':
nextToken = inputExprScanner.next();
nextItem = nextToken.charAt(0);
// Step 4: If you see an operator, push operator object onto the expressionStack
if (nextItem == '+') {
exprStack.push(nextItem);
} else if (nextItem == '-') {
exprStack.push(nextItem);
} else if (nextItem == '*') {
exprStack.push(nextItem);
}else if (nextItem == '/'){
exprStack.push(nextItem);
}
else {
exprStack.push(nextItem);
}
break;
// Step 5: If you see ")" // steps 6,7,8 in evaluateCurrentOperation()
case ')':
try {
evaluateCurrentOperation();
} catch (EmptyStackException e) {
break;
}
break;
default: // error
throw new RuntimeException(item + " is not a legal expression operator");
} // end switch
} // end else
} // end while
// Step 9: If you run out of tokens, the value on the top of expressionStack is
// is the result of the expression.
//
// return result
double result = (Double) exprStack.pop();
return result;
}
}
/*
// This static method is used by main() only
private static void evaluateExprt(String s, SimpleLispExpressionEvaluator expr)
{
Double result;
System.out.println("Expression " + s);
expr.reset(s);
result = expr.evaluate();
System.out.printf("Result %.2f\n", result);
System.out.println("-----------------------------");
}
// simple tests
public static void main (String args[])
{
SimpleLispExpressionEvaluator expr= new SimpleLispExpressionEvaluator();
String test1 = "(+ (- 6) (* 2 3 4) (/ (+ 3) (* 1) (- 2 3 1)))";
String test2 = "(+ (- 632) (* 21 3 4) (/ (+ 32) (* 1) (- 21 3 1)))";
String test3 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 1) (- 2 1 )))";
String test4 = "(+ (/2))";
String test5 = "(+ (/2 3 0))";
String test6 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 3) (- 2 1 ))))";
evaluateExprt(test1, expr);
evaluateExprt(test2, expr);
evaluateExprt(test3, expr);
evaluateExprt(test4, expr);
evaluateExprt(test5, expr);
evaluateExprt(test6, expr);
} }
*/
And heres the Array Stack:
public class ArrayStack implements BoundedStack
{
private int top;
private Object stk[];
private int size;
private int capacity;
public ArrayStack(){
top=-1;
capacity=50;
stk=new Object[capacity];
}
public ArrayStack(int cap)
{
top=-1;
size=0;
capacity=cap;
stk=new Object[capacity];
}
public void push(Object item) throws FullStackException
{
if(isFull()){
throw new FullStackException("The stack is full. Cannot push more elements onto the stack");}
else
{
stk[++top]=item;
}
}
public Object pop() throws EmptyStackException
{
if(isEmpty()==true)
{
throw new EmptyStackException("The stack is empty. Cannot pop another element from the stack");
}
else{
Object e=stk[top];
stk [top]=null;
--top;
return e;
}
}
public Object top() throws EmptyStackException{
if(isEmpty()==true){
throw new EmptyStackException("The stack is empty. Thus, it has no top");
}
return stk[top];
}
public int size(){
return (top+1);
}
public boolean isFull(){
if (size()==capacity){
return true;}
return false;
}
public boolean isEmpty(){
if(size()==0){
return true;}
return false;
}
public int capacity(){
return capacity;
}
}
The most obvious reason for this is you have not initialized your array elements before using it.
If you are creating an array like: -
SomeClass[] arr = new SomeClass[5];
Then before using your array, you need to initialize each array elements like this: -
for (int i = 0; i < arr.length; i++) {
arr[i] = new SomeClass();
}
If the line causing the NullPointerException is the line
exprStack.push(nextItem);
then the problem is not in the stack class. The problem is that exprStack is null (probably because it has never been assigned anything before this line).
You're making the same error as the following one several times in your code:
public void reset(String inputExpression) {
inputExpr = inputExpression;
StackList exprStack=new StackList(50);
StackList tempStack=new StackList(50);
}
The two last lines are completely useless: they assign a new StackList to a local variable. So the stack is created, and is immediately eligible to garbage collection, since nothing references it except a local variable that goes out of scope.
Here's another place where it happens:
if (mode.equals("0")){
exprStack=new StackList(50);
tempStack=new StackList(50);
}
else {
ArrayStack exprStack=new ArrayStack(50);
ArrayStack tempStack=new ArrayStack(50);
}