JAVA Evaluating postfix expressions -- unable to throw empty or invalid expressions - java

I'm writing a program that will evaluate a postfix expression and print both the original expression and the result. But I want to account for the validity of the expression as well. For this, I've written two exception classes -- one for an empty collection and one for invalid postfix expressions. But my code is getting stuck somewhere; my output evaluates the first expression correctly, but then only prints the original postfix expressions after that. I believe the problem is perhaps coming from my PostfixEvaluator class (see below), where I attempt to check for the size of my stack in the evaluate method. When commented out, my postfix expressions evaluate (albeit without the exceptions being caught, but still, it's something).
My code and resulting output:
Postfix Tester:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class PostfixTester
{
/**
* Reads and evaluates multiple postfix expressions.
* #throws FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException{
String expression, again;
int result;
//Scanner in = new Scanner(System.in);
Scanner in = new Scanner(new File("test.txt"));
PostfixEvaluator evaluator = new PostfixEvaluator();
while(in.hasNext()){
expression = in.nextLine();
System.out.println(expression);
try{
result = evaluator.evaluate(expression);
System.out.println("The result is: " + result);
}
catch(EmptyCollectionException e){
e.getMessage();
}
catch(InvalidPostfixExpressionException e){
e.getMessage();
}
System.out.println();
}
}
}
Postfix Evaluator:
import java.util.Stack;
import java.util.Scanner;
public class PostfixEvaluator
{
private final static char ADD = '+';
private final static char SUBTRACT = '-';
private final static char MULTIPLY = '*';
private final static char DIVIDE = '/';
private ArrayStack<Integer> stack;
/**
* Sets up this evalutor by creating a new stack.
*/
public PostfixEvaluator()
{
stack = new ArrayStack<Integer>();
}
/**
* Evaluates the specified postfix expression. If an operand is
* encountered, it is pushed onto the stack. If an operator is
* encountered, two operands are popped, the operation is
* evaluated, and the result is pushed onto the stack.
* #param expr string representation of a postfix expression
* #return value of the given expression
*/
public int evaluate(String expr)
{
int op1, op2, result = 0;
String token;
Scanner parser = new Scanner(expr);
while (parser.hasNext())
{
token = parser.next();
if (isOperator(token))
{
op2 = (stack.pop()).intValue();
op1 = (stack.pop()).intValue();
result = evaluateSingleOperator(token.charAt(0), op1, op2);
stack.push(new Integer(result));
}
else
stack.push(new Integer(Integer.parseInt(token)));
}
if(stack.size() != 1){
throw new InvalidPostfixExpressionException();
}
return result;
}
/**
* Determines if the specified token is an operator.
* #param token the token to be evaluated
* #return true if token is operator
*/
private boolean isOperator(String token)
{
return ( token.equals("+") || token.equals("-") ||
token.equals("*") || token.equals("/") );
}
/**
* Peforms integer evaluation on a single expression consisting of
* the specified operator and operands.
* #param operation operation to be performed
* #param op1 the first operand
* #param op2 the second operand
* #return value of the expression
*/
private int evaluateSingleOperator(char operation, int op1, int op2)
{
int result = 0;
switch (operation)
{
case ADD:
result = op1 + op2;
break;
case SUBTRACT:
result = op1 - op2;
break;
case MULTIPLY:
result = op1 * op2;
break;
case DIVIDE:
result = op1 / op2;
}
return result;
}
}
My ArrayStack class:
import java.util.Arrays;
public class ArrayStack<T> implements StackADT<T>
{
private final static int DEFAULT_CAPACITY = 100;
private int top;
private T[] stack;
/**
* Creates an empty stack using the default capacity.
*/
public ArrayStack()
{
this(DEFAULT_CAPACITY);
}
/**
* Creates an empty stack using the specified capacity.
* #param initialCapacity the initial size of the array
*/
public ArrayStack(int initialCapacity)
{
top = 0;
stack = (T[])(new Object[initialCapacity]);
}
/**
* Adds the specified element to the top of this stack, expanding
* the capacity of the array if necessary.
* #param element generic element to be pushed onto stack
*/
public void push(T element)
{
if (size() == stack.length)
expandCapacity();
stack[top] = element;
top++;
}
/**
* Creates a new array to store the contents of this stack with
* twice the capacity of the old one.
*/
private void expandCapacity()
{
stack = Arrays.copyOf(stack, stack.length * 2);
}
/**
* Removes the element at the top of this stack and returns a
* reference to it.
* #return element removed from top of stack
* #throws EmptyCollectionException if stack is empty
*/
public T pop() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
top--;
T result = stack[top];
stack[top] = null;
return result;
}
/**
* Returns a reference to the element at the top of this stack.
* The element is not removed from the stack.
* #return element on top of stack
* #throws EmptyCollectionException if stack is empty
*/
public T peek() throws EmptyCollectionException
{
if (isEmpty())
throw new EmptyCollectionException("stack");
return stack[top-1];
}
/**
* Returns true if this stack is empty and false otherwise.
* #return true if this stack is empty
*/
public boolean isEmpty()
{
// To be completed as a Programming Project
return top==0;
}
/**
* Returns the number of elements in this stack.
* #return the number of elements in the stack
*/
public int size()
{
// To be completed as a Programming Project
return top;
}
/**
* Returns a string representation of this stack.
* #return a string representation of the stack
*/
public String toString()
{
return stack.toString();
}
}
My input file of expressions (for testing purposes, the final two should throw the two exceptions):
8 4 + 3 *
7 5 2 * +
3 1 + 4 2 - *
5 8 2 - +
5 8 - +
6 3 2 -
My actual output:
8 4 + 3 *
The result is: 36
7 5 2 * +
3 1 + 4 2 - *
5 8 2 - +
5 8 - +
6 3 2 -
Obviously, I was expecting the first four expressions to follow as the first one did, and the final two to display my exception messages, but I can't seem to figure out where I've gone wrong.

You push the result to the evaluator stack.
You reuse the evaluator in the tester.
The evaluator is not clean when you start the second iteration in tester (the result of the previous expression is in the stack).
The easiest (and the correct) way to fix this is to change "return result;" to "return stack.pop();"
Next time use a debugger and step through your failing code. It's one of the most useful skills you can have in programming.
Asserting preconditions would help too. Check that stack is empty when you start evaluating an expression.

The exceptions are thrown but since class PostfixTester is using e.getMessgage(), you won't see the error in the output.
You should use, System.out.println(e.getMessage()) in order to print message. But even this change will print null.
You need to catch exceptions in PostfixEvaluator.evaluate() method and throw again with the message.

Related

Creating condition statement with ANTLR 4 and Java

So I'm trying to build myself my own programming language with swedish syntax(most for fun) and I have successfully managed to create variables and do some basic arithmetic on them. Moving on to do some conditional statements, I ran into some trouble. To start off, here is my (relevant) code:
SPL.g4 //My grammar file.
grammar SPL;
file
:code
;
code
:statement ';' code
;
statement
:print
|assign
|decl
|loop
|condition
;
//Declares variable
decl
:'variabel' ID
;
//Assign variable with an expression.
assign
:ID '=' expr
;
//A general expression.
expr
:'-' expr #unaryMinusExpr
|'!' expr #notExpr
|expr op=('/' | '*') expr #multiplicationExpr
|expr op=('+' | '-') expr #additiveExpr
|expr op=('<=' |'>=' | '<' | '>') expr #relationalExpr
|expr op=('=' | '!=') expr #equalityExpr
|expr 'OCH' expr #andExpr
|expr 'ELLER' expr #orExpr
|atomExpr #atom
;
//An atomic expression, more or less just a variable.
atomExpr
:ID
|INT
|'(' expr ')'
;
ID:('a'..'z')+ ;
STR:([a-zA-Z_] [a-zA-Z_0-9]*)+ ;
INT:([0-9]+)+ ;
WS: [ \n\t\r]+ -> skip ;
//Prints expr to the console
print
: 'skriv' expr
;
//Supposed to be some kind of loop and condition WORK IN PROGRESS!
condition
:'om' conditionCode ('annars om' conditionCode)* ('annars' otherBlock)?
;
conditionCode
: expr otherBlock
;
otherBlock
:'{'file'}'
| code
;
loop
:'när' expr ';'
;
Interpreter
import grammar.SPLBaseListener;
import grammar.SPLParser;
import org.antlr.v4.runtime.Token;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
/**
* Interpretes the code genereated by the parser.
* Overrides methods from the TestBaseListener so we can decide what happends.
* Created by student on 2017-01-27.
*
*/
public class Interpreter extends SPLBaseListener {
/**
* A class that holds a value. Used for storing key & value pairs in a hashmap.
*/
private static class Variable {
int val;
public Variable(int val) {
this.val = val;
}
}
private final HashMap<String, Variable> vars = new HashMap<>(); //Stores keys and values.
private Stack<Integer> exprVal = new Stack<>(); //Stores the current values.
private Stack<Boolean> conditionBooleans = new Stack<>(); //Stores the evaluated conditions
/**
* Returns a variable from the hashmap given the variable's name.
*
* #param tok
* #return
*/
private Variable getVar(Token tok) {
String name = tok.getText();
Variable v = vars.get(name);
if (v == null) {
error(tok.getLine(), "undefined " + name);
return new Variable(0); // avoid null pointer exception
} else {
return v;
}
}
/**
* When entering a declaration of a variable, we put it in the hashtable with it's name
* and a initial value of 0.
*
* #param ctx
*/
#Override
public void enterDecl(SPLParser.DeclContext ctx) {
String name = ctx.ID().getText();
Variable old = vars.put(name, new Variable(0));
if (old != null) {
error(ctx.ID().getSymbol().getLine(), "redefined " + name);
}
}
/**
* When we have exited the assignment, the variable already stored, get's the
* value that the stack is holdning.
*
* #param ctx
*/
#Override
public void exitAssign(SPLParser.AssignContext ctx) {
getVar(ctx.ID().getSymbol()).val = exprVal.pop();
}
/**
* If + add two numbers top of stack else substract them and add them back.
*
* #param ctx
*/
#Override public void exitAdditiveExpr(SPLParser.AdditiveExprContext ctx) {
String op = ctx.op.getText();
if(op.equals("+")){
exprVal.push(exprVal.pop() + exprVal.pop());
}else{ // '-'
int top = (exprVal.pop());
int second = (exprVal.pop());
exprVal.push(second - top);
}
}
/**
* If * multiplty two numbers top of stack else divide them and add them back.
*
* #param ctx
*/
#Override public void exitMultiplicationExpr(SPLParser.MultiplicationExprContext ctx) {
String op = ctx.op.getText();
if(op.equals("*")){
exprVal.push(exprVal.pop() * exprVal.pop());
}else{// '/'
int top = (exprVal.pop());
int second = (exprVal.pop());
exprVal.push(second / top);
}
}
/**
* Takes the two top elements from the stack and compares them.
* #param ctx
*/
#Override public void exitRelationalExpr(SPLParser.RelationalExprContext ctx) {
System.out.println("Im here checking relation! " + exprVal.size());
int top = (exprVal.pop());
int second = (exprVal.pop());
switch (ctx.op.getText()) {
case "<=":
System.out.println("<=");
if(top<=second)
conditionBooleans.push(true);
break;
case ">=":
System.out.println(">=");
if(top>=second)
conditionBooleans.push(true);
break;
case "<":
System.out.println("<");
if(top<second)
conditionBooleans.push(true);
break;
case ">":
System.out.println(">");
if(top>second)
conditionBooleans.push(true);
break;
default:
conditionBooleans.push(false);
}
}
/**
* Decides what codeblock to run. TODO DOES NOT WORK!
* #param ctx
*/
#Override public void enterCondition(SPLParser.ConditionContext ctx) {
System.out.println("\n CONDITION ENTERED------------------------------------------------------------------");
System.out.println(ctx.conditionCode().get(0).getText());
}
/**
* When a atomexpression is declared in code
* and if it's not null it will be pushed onto the stack.
*
* #param ctx
*/
#Override
public void enterAtomExpr(SPLParser.AtomExprContext ctx) {
if (ctx.ID() != null) {
exprVal.push(getVar(ctx.ID().getSymbol()).val);
} else if (ctx.INT() != null) {
exprVal.push(Integer.parseInt(ctx.INT().getText()));
}
}
/**
* Prints the value of exprValue.
*
* #param ctx
*/
#Override
public void exitPrint(SPLParser.PrintContext ctx) {
System.out.println("Utskrift:");
System.out.println(exprVal.pop());//Pop off the top value and print it.
}
/**
* Prints error message to the console.
*
* #param line
* #param msg
*/
private void error(int line, String msg) {
System.err.println(":" + line + ": " + msg);
}
}
test.t //the test file I'm using
variabel a;
variabel b;
a = 10;
b = 20;
a = a + b;
om a < b{
skriv a;
};
So when the interpreter reaches the if statement, that is first getting evaluated, and then it goes on to evaluate the expression. I am not sure of the order here and what to do. I believe I should save the value of the condition so I can retrieve it later on and decide on which codeblock to run. But I'm totaly lost on where to even begin.

remove & replace methods for java

So I am having alot of difficulty conceptualizing answers for the following questions. I am not looking for answers but rather useful steps that I can take that will enable me to present the answers on my own. Note: to answer these questions I am given classes referenced, and a driver program. The questions are as follows:
Q.1 Implement a method replace for the ADT bag that replaces and returns any object currently in a bag with a
given object.
Q.2.Write a remove method to remove every instance of an element in an ArrayBag.
Q.3. Give at least two examples of a situation where a fixed bag is appropriate and two examples of a situation where a resizable bag is appropriate.
The following code is what I have started but am not sure if I am in right direction:
a.1 public T replace(T theItem) {
Random generator = new Random();
int randomPosition = generator.nextInt(numberOfEntries);
T result = null;
if (!isEmpty() && (randomPosition >= 0)) {
result = bag[randomPosition]; // Entry to remove
bag[randomPosition] = theItem; // Replace entry to remove with
// last entry
}
return result;
a.2 public void clear(T theItem) {
while (!this.isEmpty(ArrayBag))
this.remove();
a.3 not sure it should be related to coding examples or something else.
Additionally, the class for the ArrayBag is below for reference:
import java.util.Arrays;
import java.util.Random;
public final class ArrayBag<T> implements BagInterface<T> {
private final T[] bag;
private int numberOfEntries;
private boolean initialized = false;
private static final int DEFAULT_CAPACITY = 25;
private static final int MAX_CAPACITY = 10000;
/** Creates an empty bag whose initial capacity is 25. */
public ArrayBag() {
this(DEFAULT_CAPACITY);
} // end default constructor
/**
* Creates an empty bag having a given capacity.
*
* #param desiredCapacity
* The integer capacity desired.
*/
public ArrayBag(int desiredCapacity) {
if (desiredCapacity <= MAX_CAPACITY) {
// The cast is safe because the new array contains null entries
#SuppressWarnings("unchecked")
T[] tempBag = (T[]) new Object[desiredCapacity]; // Unchecked cast
bag = tempBag;
numberOfEntries = 0;
initialized = true;
} else
throw new IllegalStateException("Attempt to create a bag "
+ "whose capacity exceeds " + "allowed maximum.");
} // end constructor
/**
* Adds a new entry to this bag.
*
* #param newEntry
* The object to be added as a new entry.
* #return True if the addition is successful, or false if not.
* /
public boolean add(T newEntry) {
checkInitialization();
boolean result = true;
if (isArrayFull()) {
result = false;
} else { // Assertion: result is true here
bag[numberOfEntries] = newEntry;
numberOfEntries++;
} // end if
return result;
} // end add
/**
* Retrieves all entries that are in this bag.
*
* #return A newly allocated array of all the entries in this bag.
*/
public T[] toArray() {
checkInitialization();
// The cast is safe because the new array contains null entries.
#SuppressWarnings("unchecked")
T[] result = (T[]) new Object[numberOfEntries]; // Unchecked cast
for (int index = 0; index < numberOfEntries; index++) {
result[index] = bag[index];
} // end for
return result;
// Note: The body of this method could consist of one return statement,
// if you call Arrays.copyOf
} // end toArray
/**
* Sees whether this bag is empty.
*
* #return True if this bag is empty, or false if not.
*/
public boolean isEmpty() {
return numberOfEntries == 0;
} // end isEmpty
/**
* Gets the current number of entries in this bag.
*
* #return The integer number of entries currently in this bag.
*/
public int getCurrentSize() {
return numberOfEntries;
} // end getCurrentSize
/**
* Counts the number of times a given entry appears in this bag.
*
* #param anEntry
* The entry to be counted.
* #return The number of times anEntry appears in this ba.
*/
public int getFrequencyOf(T anEntry) {
checkInitialization();
int counter = 0;
for (int index = 0; index < numberOfEntries; index++) {
if (anEntry.equals(bag[index])) {
counter++;
} // end if
} // end for
return counter;
} // end getFrequencyOf
/**
* Tests whether this bag contains a given entry.
*
* #param anEntry
* The entry to locate.
* #return True if this bag contains anEntry, or false otherwise.
*/
public boolean contains(T anEntry) {
checkInitialization();
return getIndexOf(anEntry) > -1; // or >= 0
} // end contains
/** Removes all entries from this bag. */
public void clear() {
while (!this.isEmpty())
this.remove();
} // end clear
/**
* Removes one unspecified entry from this bag, if possible.
*
* #return Either the removed entry, if the removal was successful, or null.
*/
public T remove() {
checkInitialization();
T result = removeEntry(numberOfEntries - 1);
return result;
} // end remove
/**
* Removes one occurrence of a given entry from this bag.
*
* #param anEntry
* The entry to be removed.
* #return True if the removal was successful, or false if not.
*/
public boolean remove(T anEntry) {
checkInitialization();
int index = getIndexOf(anEntry);
T result = removeEntry(index);
return anEntry.equals(result);
} // end remove
public boolean removeRandom() {
Random generator = new Random();
int randomPosition = generator.nextInt(numberOfEntries);
T result = removeEntry(randomPosition);
if (result == null) {
return false;
} else {
return true;
}
}
#Override
public boolean equals(Object obj) {
if (obj instanceof ArrayBag) {
ArrayBag<T> otherArrayBag = (ArrayBag<T>) obj;
if (numberOfEntries == otherArrayBag.numberOfEntries) {
// I create new arrays so that I can manipulate them
// and it will not alter this.bag or otherArrayBag.bag
T[] currentBagTempArray = toArray();
T[] otherBagTempArray = otherArrayBag.toArray();
Arrays.sort(currentBagTempArray);
Arrays.sort(otherBagTempArray);
for (int i = 0; i < numberOfEntries; i++) {
if (!currentBagTempArray[i].equals(otherBagTempArray[i])) {
return false;
}
}
return true;
} else {
return false;
}
} else {
return false;
}
}
public ResizableArrayBag<T> createResizableArray() {
T[] currentBagContents = toArray();
ResizableArrayBag<T> newBag = new ResizableArrayBag<T>(currentBagContents);
return newBag;
}
// Returns true if the array bag is full, or false if not.
private boolean isArrayFull() {
return numberOfEntries >= bag.length;
} // end isArrayFull
// Locates a given entry within the array bag.
// Returns the index of the entry, if located,
// or -1 otherwise.
// Precondition: checkInitialization has been called.
private int getIndexOf(T anEntry) {
int where = -1;
boolean found = false;
int index = 0;
while (!found && (index < numberOfEntries)) {
if (anEntry.equals(bag[index])) {
found = true;
where = index;
} // end if
index++;
} // end while
// Assertion: If where > -1, anEntry is in the array bag, and it
// equals bag[where]; otherwise, anEntry is not in the array.
return where;
} // end getIndexOf
// Removes and returns the entry at a given index within the array.
// If no such entry exists, returns null.
// Precondition: 0 <= givenIndex < numberOfEntries.
// Precondition: checkInitialization has been called.
private T removeEntry(int givenIndex) {
T result = null;
if (!isEmpty() && (givenIndex >= 0)) {
result = bag[givenIndex]; // Entry to remove
int lastIndex = numberOfEntries - 1;
bag[givenIndex] = bag[lastIndex]; // Replace entry to remove with
// last entry
bag[lastIndex] = null; // Remove reference to last entry
numberOfEntries--;
} // end if
return result;
} // end removeEntry
// Throws an exception if this object is not initialized.
private void checkInitialization() {
if (!initialized)
throw new SecurityException(
"ArrayBag object is not initialized properly.");
} // end checkInitialization
} // end ArrayBag
Someone else implemented Bag using an Array at Bag Class Implementation in Java/Using Array . I only glanced at the code, so it may be a mixed Bag.
I'm assuming that Bag is like a Set, except in can store the same object more than once.
You would want to implement a private collection of some sort (perhaps an Array like above). Let's call it myBag.
Since you're using a generic type T, your Bag will only contain objects of type T.
For Q1, your replace() method might need to take two parameters: The object to be replaced (say findMe) and the object you're replacing it with (say replacement).
If your Bag can hold duplicates, then you will probably want to replace the first object that matches.
Rather than use Random(), you might need to go element by element through myBag, and replace the found element with the one you're replacing. You might want to throw an error if findMe is not found. So the method declaration might be something like:
public boolean replace(T findMe, T replacement)
and return true if findMe was found, false otherwise.
For Q2, you could create a while loop that removes the first element in myBag while the size of myBag was > 0.
For Q3, thre's no coding involved. This is a thinking question. In general, a fixed size Bag would be helpful when the size is known at the beginning will not change.
A resizable bag makes sense in more cases, where you don't know the size at the beginning and it is likely to shrink or grow, for example, a waiting list for a class.
I looked your starting code and class but I did not run it.
But I can say that you are in right direction.
For Q2, You should search the given element in array and remove the each one. Because question clearly says that "remove every instance of an element " Please check the getIndexOf() method. You can see how to search and element. If you find one matching remove it. Be careful if you remove and element while you are iterating over it. If you delete one element while you are iterating size will change. I offer you to store each matching on an array. After iteration use remove(index) method for each found element
Give at least two examples of a situation where a fixed bag is appropriate and two examples of a situation where a resizable bag is appropriate.
For this item you can add some explanation and some sample code or algorithm.
I can offer you two thing:
1. If the array is not getting full too fast fixed size is good. But if array is getting full too fast you should resize new array and copy all elements again and again. Overhead amount is important.
2. Amount of capacity is important. How you will decide initial size ? Big size or small size ? Think that
I hope this helps

Strange output(square symbol) in the Java code

everyone. I am currently having issue on doing the evaluation of postfix expression in Java and I think everything is alright except the output is not really correct. But never mind, please let me to post all the codes so that all of you can have a look on them. By the way, please be noted that all of you just need to concentrate on TestPalindrome class is enough because I never change the codes for the other classes except the class that I specified just now.
StackInterface defines all the methods that are available to ArrayStack class.
//There is no need to check this.
public interface StackInterface<T> {
/** Task: Adds a new entry to the top of the stack.
* #param newEntry an object to be added to the stack */
public void push(T newEntry);
/** Task: Removes and returns the stack誷 top entry.
* #return either the object at the top of the stack or, if the
* stack is empty before the operation, null */
public T pop();
/** Task: Retrieves the stack誷 top entry.
* #return either the object at the top of the stack or null if
* the stack is empty */
public T peek();
/** Task: Detects whether the stack is empty.
* #return true if the stack is empty */
public boolean isEmpty();
/** Task: Removes all entries from the stack */
public void clear();
} // end StackInterface
ArrayStack class that is nothing special.
//There is no need to check this.
public class ArrayStack<T> implements StackInterface<T> {
private T[] stack; // array of stack entries
private int topIndex; // index of top entry
private static final int DEFAULT_INITIAL_CAPACITY = 50;
public ArrayStack() {
this(DEFAULT_INITIAL_CAPACITY);
} // end default constructor
public ArrayStack(int initialCapacity) {
stack = (T[]) new Object[initialCapacity];
topIndex = -1;
} // end constructor
public void push(T newEntry) {
topIndex++;
if (topIndex >= stack.length) // if array is full,
doubleArray(); // expand array
stack[topIndex] = newEntry;
} // end push
public T peek() {
T top = null;
if (!isEmpty())
top = stack[topIndex];
return top;
} // end peek
public T pop() {
T top = null;
if (!isEmpty()) {
top = stack[topIndex];
stack[topIndex] = null;
topIndex--;
} // end if
return top;
} // end pop
public boolean isEmpty() {
return topIndex < 0;
} // end isEmpty
public void clear() {
} // end clear
/** Task: Doubles the size of the array of stack entries.
* Refer to Segment 5.18 */
private void doubleArray() {
T[] oldStack = stack; // get reference to array of stack entries
int oldSize = oldStack.length; // get max size of original array
stack = (T[]) new Object[2 * oldSize]; // double size of array
// copy entries from old array to new, bigger array
System.arraycopy(oldStack, 0, stack, 0, oldSize);
} // end doubleArray
} // end ArrayStack
The following class is TestPalindrome class.(The class name may sounds strange because the exercises that I did were all in the same class and I do not post the irrelevant codes in the class.)
import java.util.Scanner;
public class TestPalindrome {
public TestPalindrome() {
}
public static void main(String[] args) {
//P3Q2
StackInterface<Character> myStack = new ArrayStack<Character>();
Scanner scanner = new Scanner(System.in);
int result;
char resultInChar;
System.out.print("Please enter a postfix expresion : ");
String postfix = scanner.nextLine();
for(int i = 0; i < postfix.length(); i++)
{
char postfixChar = postfix.charAt(i);
if(Character.isDigit(postfixChar)) //If postfixChar is a digit, then it will be pushed into the stack.
{
myStack.push(postfixChar);
}
/*(For else statement) First operand will be popped as right operand and second
operand will be popped as left operand if postfixChar is operator such as + .
The calculation of both operands will be carried out based on the operator given.
After this the result of calculation will be pushed back into the stack and the
same things will happen again.*/
else
{
int firstOperand = Character.getNumericValue(myStack.pop()); //To get numeric value of the first character stored.
System.out.println("\nThe right operand : " + firstOperand);
int secondOperand = Character.getNumericValue(myStack.pop()); //To get numeric value of the second character stored.
System.out.println("The left operand : " + secondOperand);
switch(postfixChar)
{
case '+':
result = secondOperand + firstOperand;
System.out.println("The result is " + result);
resultInChar = (char)result; //Convert the result of calculation back to character data type so that it can be pushed into the stack.
System.out.println("Strange output : " + resultInChar); //Here is where the strange output occurred.
myStack.push(resultInChar);
break;
case '-':
result = secondOperand - firstOperand;
System.out.println("The result is " + result);
resultInChar = (char)result;
myStack.push(resultInChar);
break;
case '/':
result = secondOperand / firstOperand;
System.out.println("The result is " + result);
resultInChar = (char)result;
myStack.push(resultInChar);
break;
case '*':
result = secondOperand * firstOperand;
System.out.println("The result is " + result);
resultInChar = (char)result;
myStack.push(resultInChar);
break;
}
}
}
System.out.println("\nThe answer of " + postfix + " is " + Character.getNumericValue(myStack.pop())); //To get the final answer in the form of numeric value
}
}
Here is the attachment of the picture to show all the outputs of the program.
Please explain the wrong part as I really cannot figure out why this will happen since 1 + 1 = 2 and the ASCII code of 2 which is 50 should be displayed instead of the weird square symbol.Thanks because spending the valuable time to look into my problem.
You say:
Please explain the wrong part as I really cannot figure out why this
will happen since 1 + 1 = 2 and the ASCII code of 2 which is 50 should
be displayed instead of the weird square symbol.
Yes, 1 + 1 = 2. But if you cast it to a char, it will use ASCII value 2, and not 50. To do that, you should do something like:
resultCharIn = (char) ('0' + result);
In other words: '0' != 0.
However, this seems like a wrong approach, because: what if the result is greater than 9. You will need two characters. Maybe you should consider a different design?

Why is my object staying null?

For some reason, I can't seem to fix this giving me a NullPointerException. I print out poly.term.degree without any errors, and then set poly.next equal to poly and then get a nullPointerException when I try to print out poly.next.term.degree which should seemingly be the same. I'm aware this is incomplete code but I think this is my main issue.
public Polynomial add(Polynomial p)
{
Polynomial newPoly = new Polynomial();
newPoly.poly = new Node(0,0,null);
Polynomial myCurr = this;
Polynomial otherCurr = p;
while(myCurr.poly != null)
{
int myDeg = myCurr.poly.term.degree;
int otherDeg = p.poly.term.degree;
float myCo = myCurr.poly.term.coeff;
float otherCo = otherCurr.poly.term.coeff;
if(myDeg == otherDeg)
{
System.out.println("degrees "+myDeg + " and "+ otherDeg+ " are equal, creating new node...");
Node n = new Node(myCo+otherCo,p.poly.term.degree, newPoly.poly.next);
System.out.println(newPoly.poly.term.degree);
newPoly.poly.next = newPoly.poly;
newPoly.poly = n;
System.out.println(newPoly.poly.next.term.degree); // Gives me a NullPointerException
}
Also, the constructors and everything for these classes is below.
package poly;
import java.io.*;
import java.util.StringTokenizer;
/**
* This class implements a term of a polynomial.
*
* #author runb-cs112
*
*/
class Term {
/**
* Coefficient of term.
*/
public float coeff;
/**
* Degree of term.
*/
public int degree;
/**
* Initializes an instance with given coefficient and degree.
*
* #param coeff Coefficient
* #param degree Degree
*/
public Term(float coeff, int degree) {
this.coeff = coeff;
this.degree = degree;
}
/* (non-Javadoc)
* #see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object other) {
return other != null &&
other instanceof Term &&
coeff == ((Term)other).coeff &&
degree == ((Term)other).degree;
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
public String toString() {
if (degree == 0) {
return coeff + "";
} else if (degree == 1) {
return coeff + "x";
} else {
return coeff + "x^" + degree;
}
}
}
/**
* This class implements a linked list node that contains a Term instance.
*
* #author runb-cs112
*
*/
class Node {
/**
* Term instance.
*/
Term term;
/**
* Next node in linked list.
*/
Node next;
/**
* Initializes this node with a term with given coefficient and degree,
* pointing to the given next node.
*
* #param coeff Coefficient of term
* #param degree Degree of term
* #param next Next node
*/
public Node(float coeff, int degree, Node next) {
term = new Term(coeff, degree);
this.next = next;
}
}
/**
* This class implements a polynomial.
*
* #author runb-cs112
*
*/
public class Polynomial {
/**
* Pointer to the front of the linked list that stores the polynomial.
*/
Node poly;
/**
* Initializes this polynomial to empty, i.e. there are no terms.
*
*/
public Polynomial() {
poly = null;
}
/**
* Reads a polynomial from an input stream (file or keyboard). The storage format
* of the polynomial is:
* <pre>
* <coeff> <degree>
* <coeff> <degree>
* ...
* <coeff> <degree>
* </pre>
* with the guarantee that degrees will be in descending order. For example:
* <pre>
* 4 5
* -2 3
* 2 1
* 3 0
* </pre>
* which represents the polynomial:
* <pre>
* 4*x^5 - 2*x^3 + 2*x + 3
* </pre>
*
* #param br BufferedReader from which a polynomial is to be read
* #throws IOException If there is any input error in reading the polynomial
*/
public Polynomial(BufferedReader br) throws IOException {
String line;
StringTokenizer tokenizer;
float coeff;
int degree;
poly = null;
while ((line = br.readLine()) != null) {
tokenizer = new StringTokenizer(line);
coeff = Float.parseFloat(tokenizer.nextToken());
degree = Integer.parseInt(tokenizer.nextToken());
poly = new Node(coeff, degree, poly);
}
}
I think the problem lies here:
newPoly.poly.next = newPoly.poly;
newPoly.poly = n;
At first you say, that newPoly.poly.next = newPoly.poly; so you assign the current element to the next, which is recursive. And then you say newPoly.poly = n; . So you assign a new element to newPoly. I think that the garbage collector deletes the newPoly element, because it is overwritten, so you lose the reference to the newPoly element. Which means when you access it later you get a nullpointer exception. You could fix this like this:
newPoly.poly.next = n;
//and dont forget to set the next pointer of the new elemnt to 0
n.next = NULL;
Just assign the new element to the next element.
EDIT
#hendersawn
You could sort the list. See below:
sort(Node head_p){ //do not change the head, or you will lose the beginning.
Node tmp_p;
Node curr_p = head_p;
while(curr_p != NULL){
if(curr_p.poly.term.degree < curr_p.next.poly.term.degree) //either degree is smaller or greater
{//swap
tmp_p = curr_p; //save first element
curr_p = curr_p.next; //set first element to second
//now the 2 element is the actual third element so we need
//to put the first between the second and the third
tmp_p.next = curr_p.next; //set next of first to third
curr_p.next = tmp_p; //set second element to the first that we saved before
}
curr_p = curr_p.next; //move to next element...rinse repeat
}
}
newPoly might be null
newPoly.poly might be null
newPoly.poly.next might be null
newPoly.poly.next.term might be null
or
newPoly.poly.next.term.degree might be null.
To avoid NullPointerException, you need to make sure that any member used is initialized with a proper value.
Nothing is obviously null that I can tell, however with four 'dots' (something.something.something.something) of Object Oriented Indirection, you're going to encounter this problem a lot. Usually two - three 'dots' on a single line are all you should ever do, but since that's more about the design and not the error, I digress.
The way to find this problem would be to either:
Put a breakpoint right at that line and see what the variables are there, and which one is null or
Do a System.out.println for each of the components to see which one breaks it, and work backwards from there. ex:
System.out.println(newPoly.poly.next.term.degree); // Gives me a NullPointerException
System.out.println(newPoly);
System.out.println(newPoly.poly);
System.out.println(newPoly.poly.next);
System.out.println(newPoly.poly.next.term);
because the nullPointerException would only get thrown on one of those (it can't be degree, otherwise that statement would have just printed 'null'
if I had to bet, I'd say it's probably newPoly.poly.next which is null
the lines:
newPoly.poly.next = newPoly.poly;
newPoly.poly = n;
Superficially seem like they would be the culprit of your trouble, since you're assigning the 'next' of your newPoly.poly, but then you re-assign your newPoly.poly, and lose that old reference to .next, I think.
Good luck! hope that helps.

HexapawnBoard class in Java

I have to complete 4 methods but I am having difficulty understanding them. I'm trying to complete whitemove(). I know that I have to iterate through the board, but I cannot totally understand how I'm supposed to do it!
import java.util.List;
import java.util.ArrayList;
public class HexapawnBoard {
private static final int WHITE_PIECE = 1;
private static final int BLACK_PIECE = 2;
private static final int EMPTY = 0;
private static final int BOARD_SIZE = 3;
private int[][] board;
/**
* Create a board position from a string of length BOARD_SIZE*BOARD_SIZE (9).
* The first BOARD_SIZE positions in the string correspond to the black player's home
* position. The last BOARD_SIZE positions in the string correspond ot the white player's
* home position. So, the string "BBB WWW" corresponds to a starting position.
*
* #param pos the string encoding the position of the board
*/
public HexapawnBoard(String pos)
{
if(pos.length() != BOARD_SIZE * BOARD_SIZE)
throw new RuntimeException("HexapawnBoard string must be of length BOARD_SIZExBOARD_SIZE");
board = new int[BOARD_SIZE][BOARD_SIZE];
for(int row=0;row<BOARD_SIZE;row++)
{
for(int col=0;col<BOARD_SIZE;col++)
{
switch(pos.charAt(row*BOARD_SIZE+col))
{
case 'B':
case 'b':
board[row][col] = BLACK_PIECE;
break;
case 'W':
case 'w':
board[row][col] = WHITE_PIECE;
break;
case ' ':
board[row][col] = EMPTY;
break;
default:
throw new RuntimeException("Invalid Hexapawn board pattern " + pos);
}
}
}
}
/**
* A copy constructor of HexapawnBoard
*
* #param other the other instance of HexapawnBoard to copy
*/
public HexapawnBoard(HexapawnBoard other)
{
board = new int[BOARD_SIZE][BOARD_SIZE];
for(int i=0;i<BOARD_SIZE;i++)
for(int j=0;j<BOARD_SIZE;j++)
this.board[i][j] = other.board[i][j];
}
/**
* Return a string version of the board. This uses the same format as the
* constructor (above)
*
* #return a string representation of the board.
*/
public String toString()
{
StringBuffer sb = new StringBuffer();
for(int row=0;row<BOARD_SIZE;row++)
{
for(int col=0;col<BOARD_SIZE;col++)
{
switch(board[row][col])
{
case BLACK_PIECE:
sb.append('B');
break;
case WHITE_PIECE:
sb.append('W');
break;
case EMPTY:
sb.append(' ');
break;
}
}
}
return sb.toString();
}
/**
* Determine if this board position corresponds to a winning state.
*
* #return true iff black has won.
*/
public boolean blackWins()
{
for(int col=0;col<BOARD_SIZE;col++)
if(board[BOARD_SIZE-1][col] == BLACK_PIECE)
return true;
return false;
}
/**
* Determine if this board position corresponds to a winning state
*
* #return true iff white has won
*/
public boolean whiteWins()
{
for(int col=0;col<BOARD_SIZE;col++)
if(board[0][col] == WHITE_PIECE)
return true;
return false;
}
/**
* Determine if black has a move
*
* # return truee iff black has a move
*/
public boolean blackCanMove()
{
return false;
}
/**
* Return a List of valid moves of white. Moves are represented as valid
* Hexapawn board positions. If white cannot move then the list is empty.
*
* #return A list of possible next moves for white
*/
public List<HexapawnBoard> whiteMoves()
{
return null
}
/**
* Determine if two board positions are equal
* #param other the other board position
* #return true iff they are equivalent board positions
*/
public boolean equals(HexapawnBoard other)
{
return true;
}
/**
* Determine if two board positions are reflections of each other
* #param other the other board position
* #return true iff they are equivalent board positions
*/
public boolean equalsReflection(HexapawnBoard other)
{
return true;
}
}
First of all, the code that you have so far seems to be correct.
Now, for the four methods that you have left, I can't really help you with the blackCanMove() or the whiteMoves() methods because I don't know what the rules for moving are in this hexapawn game. If you would explain the rules, I could help with that.
As far as the equals() and equalsReflection() methods go, you basically need to do what you did in the copy constructor, but instead of copying, do a conditional test. If two positions do not match up to what they are supposed to be, return false. Otherwise, once you have checked each square and they are all correct, return true.
As far as the whiteMoves() method, you need to iterate through the board and find all of the white pieces. For each white piece, there may be a few (at most 3) valid moves. Check each of those positions to see if they are possible. The piece may move diagonally if there is a black piece in that spot, or it may move forward if there is no piece at all in that spot. For each valid move, create a new HexapawnBoard representing what the board would look life following that move. At the end of the method, return a list of all of the HexapawnBoards that you created.

Categories

Resources