Beginner Stacks, OutofBoundsException Java - java

Hey I have a question as to why my program is throwing an ArrayIndextOutofBounds Exception
I've looked everywhere on the internet and have gone through the code but I know I'm missing something.
This is my first program that has implemented stacks and to be quite frank I'm not exactly 100% on what it is I am doing.
I think the problem is coming from my isEmpty method but can't exactly see what I am doing wrong.. there must be an easier way to test if a stack is empty or not?
Any help would be greatly appreciated.
PS: am I setting up my test stack correctly?
Heres my code:
import java.util.Arrays;
public class ArrayStack<T> implements StackADT<T>
{
private final static int DEFAULT_CAPACITY = 100;
private int top;
private T[] stack;
private int emptyCount = 0;
//Creates an empty stack using the default capacity.
public ArrayStack()
{
this(DEFAULT_CAPACITY);
}
//Creates an empty stack using the specified capacity.
#SuppressWarnings("unchecked")
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.*/
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.*/
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.*/
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.
public boolean isEmpty()
{
for(int i = 0; i < stack.length; i++)
{
if (stack[i] == null)
emptyCount++;
}
if(emptyCount != stack.length-1)
return false;
else
return true;
}
//Returns the number of elements in this stack.
public int size()
{
return stack.length;
}
//Returns a string representation of this stack.
public String toString()
{
String output = "The element at the top of the stack is: " + peek() + "\n" +
"It is " + isEmpty() + " that the stack is empty." + "\n" +
"The number of elements in the stack is: " + size();
return output;
}
}
And my driver/test file:
public class StackTest
{
public static void main(String[] args) throws EmptyCollectionException
{
ArrayStack stack = new ArrayStack(5);
System.out.println(stack);
}
}

Your problem is the isEmpty() method. The stack is empty when top==0 and has nothing to do with the contents of the stack elements.

i guess the problem is in the peek() function and not in isEmpty()
in peek() you use stack[top - 1] which means stack[-1]
another problem though is the size() function... it doesn't return the number of elements in the stack but the length of the stack.

the problem is in your isEmpty() method. Try do something like this
public boolean isEmpty()
{
for (T element : stack)
{
if(element != null)
{
return false;
}
}
return true;
}
another problem is your size function, it always returns the length of the array.
try do something like this:
public int size()
{
int count = 0;
for (T element : stack)
{
if(element != null)
count++;
}
return count;
}

Related

Dynamic array based stack

I'm trying to create a dynamic array based stack and I am getting an index out of bound error when I try to push elements elements onto a full array. I also made the array generic to accommodate all types of stacks.
import java.util.Arrays;
import java.util.Iterator;
public class Stack<T> {
private int topStack;
private int stackSize;
private T[] stack;
// Constructor
public Stack(T[] arr) {
stack = arr;
stackSize = arr.length;
topStack = -1;
}
// isEmpty
public boolean isEmpty() {
if (topStack == -1)
return true;
return false;
}
// isFull method
public boolean isFull() {
if ((topStack + 1) == stackSize)
return true;
return false;
}
// increment array by 10 spaces <-----------------------------------
public void incrementArray() {
T[] temp = (T[]) new Object[stackSize*2];
System.arraycopy(stack, 0, temp, 0, stack.length);
stack=temp;
stackSize=stackSize*2;
}
// decrement array
public void decrementArray() {
stackSize=stackSize/2;
T[] temp = (T[]) new Object[stackSize];
System.arraycopy(stack, 0, temp, 0, stackSize);
stack=temp;
}
// push method which adds element to top of stack
public void push(T element) {
if (isFull())
incrementArray();
topStack=topStack+1;
stack[topStack] = element;
}
// peek method which shows top of stack without popping it
public T peek() {
return stack[topStack];
}
// pop which copies top of stack, deletes top and returns copy
public T pop() throws EmptyStackException {
if (isEmpty()) {
throw new EmptyStackException();
}
int temp = topStack+1;
if(temp<stackSize/2)
decrementArray();
return stack[topStack--];
}
public static void main(String[] args) {
Stack operands = new Stack<>(new Integer[0]);
operands.push(2);
operands.push(1);
}
}
I'm trying to increase the stack size instead of having it overflow out of bounds.
You should give your stack an initial size > 0. As it stands, your initial stackSize is 0. And guess what stackSize*2 is equal to? And another observation is that you created a generic stack but did not specify a type when creating it in main
Also, note that you can change
public boolean isEmpty() {
if (topStack == -1)
return true;
return false;
}
to
public boolean isEmpty() {
return topStack == -1;
}
You can make similar changes in other methods that return a boolean.
When your code does not behave the way it should, think about what is going on and why that might happen. Placing ubiquitous print statements thru out your code is a good first step to check on key values to see if they are what you expect them to be. A more sophisticated method is to use a debugging tool to step thru your program as it executes to look at the values of various fields.

How do i implement the push pop peek methods for an inverse array?

Create a class called inverse_Stack where our 'stack' is organized in such a way where the first/"bottom" element is located at index (-1). Each element pushed is placed into the array slot before the [current] top-most element. if(size=0)store at index: (length -1); if(size=1), store at index:(length -2);if(size=2), store at index: (length-3);
This is all i have so far. Lost with the push pop peek methods for an inverse stack. I know how to make them work for a regular stack
public class Inverse_Stack<T> implements StackADT<T>{
private T[] stack;
private int top;
//private int bot;
public Inverse_Stack(){
this(100);
}
public Inverse_Stack(int capacity){
top = 0;
stack = (T[] new Object[capacity];
}
public int size(){
//returns size of array
return stack.length;
}
public void push(T element){
//fill in code
}
private void expandCapacity(){
T[] newStack = (T[] new Object[stack.length*2];
for(int i = 0; i < stack.length;i++)
newStack[i] = stack[i];
stack = newStack;
}
public T pop(){
if(isEmpty())
throw new RuntimeException("Empty Stack");
//fill in code
}
public T peek(){
if(isEmpty())
throw new RuntimeException("Empty Stack");
//fill in code
}
length tells you the capacity: the number of items the stack can hold. You also need to keep a count variable so you know how many items are currently in the stack.
I won't write the Java code, but I can give you the general idea:
In your constructor, set count to 0.
isEmpty returns true if count is greater than 0.
push
if the stack is full, expand the capacity
add element at stack[count]
increment count
pop
if the stack is empty, throw empty stack exception
decrement count
return the value at stack[count]
peek is like pop, but you don't actually decrement count.
Is not ArrayDeque doing exactly what you want?
public class InverseStack<T> extends ArrayDeque<T> {
…
}
and toArray( T[] a ) would get Your inverse array
this is my answer. I think this is more help you.
class StackX {
private int maxSize; //size of stack array
private char[] stackData;
private int top; //top of stack
//-------------------------------------------------------------------------
public StackX(int s) {
this.stackData = new char[s];
this.maxSize = s;
this.top = -1;
}
public boolean isEmpty() {
return (top == -1);
}
public boolean isFull() {
return (top == maxSize - 1);
}
public void push(char item) {
if (isFull()) {
System.out.println("Stack is full");
return;
}
stackData[++top] = item;
}
public char pop() throws Exception {
if (isEmpty()) {
throw new Exception("Stack is empty");
}
return stackData[top--];
}
public char peek() throws Exception {
if (isEmpty()) {
throw new Exception("Stack is empty");
}
char peekValue = this.pop();
this.push(peekValue);
return peekValue;
}
public void display() {
if (isEmpty()) {
System.out.println("Stack is empry");
}
System.out.println("Start printing stack data");
for (int i = top; i >= 0; i--) {
System.out.println(stackData[i]);
}
System.out.println("End printing stack data");
}
}

What is the problem with my code , I am trying to search in the stack with an internall and external method

Write a method to find the position of a given element in a stack counting from the top of the stack. More precisely,
the method should return 0 if the element occurs on the top, 1 if there is another element on top of it, and so on. If
the element occurs several times, the topmost position should be returned. If the element doesn’t occur at all, -1
must be returned.
You are asked to write this method in two different ways; one way is to implement it internally inside the
ArrayStack class and the other way is to implement it externally in a separate class. Important: At the end
the stack should be returned to the original state (i.e. no elements should be removed and the order of the elements
should not change).
This is the externall class
public class Stack{
public static int searchstack(ArrayStack z, int n) {
ArrayStack temp = new ArrayStack(z.size());
int c = 0;
boolean flag = false;
while (!z.isEmpty()) {
if (z.top() == n) {
flag = true;
return c;
}
if (z.top() != n) {
temp.push(z.pop());
c++;
flag = false;
}
}
if (flag == false) {
c = -1;
}
while (!temp.isEmpty() && !z.isFull()) {
z.push(temp.pop());
}
return c;
}
public static void main(String[] args) {
ArrayStack z = new ArrayStack(4);
z.push(3); // first element
z.push(7);// 2nd
z.push(8);// 3rd
z.push(1);// 4th
z.printStack();
int n = 3;
System.out.println("Searching externally for" + " " + n + " " + searchstack(z, n));
System.out.println("Searching internally for" +" "+n+" "+ z.searchfor(n)+" "); //THE ERROR IS HERE
}
}
And this is the ArrayClass
public class ArrayStack {
private int[] theStack;
private int maxSize;
private int top;
public ArrayStack(int s) {
maxSize = s;
theStack = new int[maxSize];
top = -1;
}
public void push(int elem) {
top++;
theStack[top] = elem;
}
public int pop() {
int result = theStack[top];
top--;
return result;
}
public int top() {
return theStack[top];
}
public boolean isFull() {
return (top == (maxSize - 1));
}
public boolean isEmpty() {
return (top == -1);
}
public int size() {
return (top + 1);
}
//HERE IS THE METHOD I IMPLEMENTED INTERNALLY AND CALL IT AT THE STACK CLASS
public int searchfor(int n) {
for (int i = top; i >= 0; i--) {
if (theStack[top] == n) {
return i;
}
}
return -1;
}
public void printStack() {
if (top == -1)
System.out.println("Stack is empty!!\n");
else {
System.out.println(theStack[top] + " <- top");
for (int i = top - 1; i >= 0; i--)
System.out.println(theStack[i]);
System.out.println();
}
}
}
The error appearing at the Stack class is at the last line of calling the searchfor method implemented in the Arraystack class , error says that there is no method implemented in Arraystack with the name searchfor (); thiugh I did implement it .whatseems to be the problem ?
You have a bug in your searchStack() implementation. You are losing elements if you find the one you are looking for and it isn't the topmost one.
How to fix your searchStack() method:
keep popping z until you have an empty ArrayStack. While doing so, add the value to a queue.
create valIndex and assign it -1.
Then go through the queue and remove the items from it and adding them to z. While doing so, check for the last occurence of the desired value and save it in valIndex.
if valIndex equals -1 return it. Else, use following equation to convert it to correct index and return:
valIndex = (z.size - 1) - valIndex

how to check when stack is empty

well this is my array stack separated from my main
i have just one problem though, my code have no problems yet it lacks
something like if i run pop yet the stack is empty, it must have a dialog saying that it is empty, i tried an if else statement yet i dont know where to put it or is it really the if else statement needed, anyways here's my code. . .
public class ArrayStack {
int STACK_MAX = 20;
int size = -1 ;
int top = -1 ;
int StackObj[] = new int[STACK_MAX];
/**************** for PUSH METHOD *********/
public void Push(int obj) {
if (size()==STACK_MAX){
System.out.println("STACK is FULL");
}
else{
StackObj[++top]= obj;
}
}
/**************** for SIZE Method ********/
public int size() {
return (top+1);
}
/******************** for Display Method****/
public void DisplayStack() {
String disp="";
for (int i=top; i>=0; i--){
disp += StackObj[i] + "\n";
}
JOptionPane.showMessageDialog(null, "Elements of the Stacks : \n" + disp);
}
/***************** for isEmpty Method *******/
public boolean isEmpty(){
return (top == -1);
}
/***************** for Top Method ***********/
public int Topmethod(){
int taas = StackObj[top];
JOptionPane.showMessageDialog(null,"Top is : "+taas);
return (top);
}
/***************** for Pop Method ***********/
public int pop(){
int topItem = StackObj[top];
top--;
JOptionPane.showMessageDialog(null,"The recently pushed number was Deleted: "+topItem);
return(top);
}
}
You would want to add something in your pop method to handle recognizing when the stack was empty then handling the case of an empty stack such as:
public int pop(){
if(size() == 0){ //detect empty stack
JFrame frame = new JFrame("my frame");; //handle empty stack
JOptionPane.showMessageDialog(frame,"Stack is empty!");
return null; //make sure you handle a null return value if you use this
}
int topItem = StackObj[top];
top--;
JOptionPane.showMessageDialog(null,"The recently pushed number was Deleted: "+topItem);
return(top);
}
here i edited it
public int pop(){
if(size() == 0){ //detect empty stack
JOptionPane.showMessageDialog(null,"Stack is empty!");
return (top); //make sure you handle a null return value if you use this
}
int topItem = StackObj[top];
top--;
JOptionPane.showMessageDialog(null,"The recently pushed number was Deleted: "+topItem);
return(top);
}

First year prgorammer needs help with a nullpointer exception in java

As a portion of a first year assignment, I need to create a class which uses a provided linked list implementation to implement a provided stack interface which is then tested by another provided class. I was able to easily complete the assignment using my own LL; however, I was told that I needed to use the one provided.
Exception in thread "main" java.lang.NullPointerException
at StackLL.<init>(StackLL.java:21)
at StackTester.main(StackTester.java:91)
Now I get null pointer exceptions whenever I try and run it. I thought this was being caused by the tester trying to grab the size of the list before the LL is initialized, but that doesn't seem to be the case and I am stumped.
Any tips on what I can do to fix the bug so that I can hand in the rest of the assignment? Thanks :)
The provided linked list implementation
LinkedList.java
/**
* LinkedList - a simple linked list of ints
*/
public class LinkedList
{
Node head;
int count;
public LinkedList ()
{
head = null;
count = 0;
}
/**
* Adds the given item to the start of the list
*/
public void addToStart (int item)
{
Node newNode = new Node();
newNode.value = item;
if (head != null)
newNode.next = head;
head = newNode;
count++;
}
/**
* Adds the given item to the end of the list
*/
public void addToEnd (int item)
{
if (size() == 0)
{
addToStart (item);
}
else
{
Node n = head;
while (n.next != null)
n = n.next;
n.next = new Node(item);
count++;
}
}
/**
* Remove and return the first item in the list
*/
public int removeFromStart ()
{
if (size() == 0)
throw new EmptyListException();
int valtoReturn = head.value;
head = head.next;
count--;
return valtoReturn;
}
/**
* Remove and return the last item in the list
*/
public int removeFromEnd ()
{
if (size() == 0)
throw new EmptyListException();
if (size() == 1)
return removeFromStart();
else
{
Node n = head;
while (n.next.next != null)
n = n.next;
int valtoReturn = n.next.value;
n.next = null;
count--;
return valtoReturn;
}
}
/**
* Return the number of items contained in this list
*/
public int size ()
{
return count;
}
/**
* A basic node class
*/
private class Node
{
int value;
Node next;
Node()
{
}
Node (int value)
{
this.value = value;
}
}
// random testing code for the Linked List
public static void main (String [] args)
{
LinkedList l = new LinkedList();
l.addToStart (5);
int val = l.removeFromStart();
System.out.println (val == 5 ? "passed" : "failed");
System.out.println (l.size() == 0 ? "passed" : "failed");
for (int x = 0; x < 10; x++)
l.addToEnd (x);
System.out.println (l.size() == 10 ? "passed" : "failed");
while (l.size() > 0)
System.out.print (l.removeFromEnd() + " ");
System.out.println ();
}
}
/**
* The exception class when a removal action is performed on
* an empty list.
*/
class EmptyListException extends RuntimeException
{
public EmptyListException ()
{
super();
}
public EmptyListException (String s)
{
super(s);
}
}
My implementation
StackLL.java
/**
* A linked list implementation of the Stack ADT.
*
*/
public class StackLL implements Stack
{
// The linked list that will contain the values in the stack
private LinkedList values;
public int size()
{
return values.size();
}
public boolean isEmpty()
{
if (values.size() <= 0) {
return true;
}
return false;
}
public void push(int element)
{
values.addToStart(element);
}
public int pop() throws StackEmptyException
{
if (values.size() == 0) {
throw new StackEmptyException();
}
else {
return values.removeFromStart();
}
}
public int peek() throws StackEmptyException
{
if (values.size() == 0) {
throw new StackEmptyException();
}
else { //This is a pretty silly way to do this, but I can't think of any other way without making my own linked list method.
int elementVal = values.removeFromStart();
values.addToStart(elementVal);
return elementVal;
}
}
}
The Provided Interface
Stack.java
/**
* Stack.java
*
* A specification of the Stack ADT
*
*/
public interface Stack
{
int size();
boolean isEmpty();
void push (int element);
int pop() throws StackEmptyException;
int peek() throws StackEmptyException;
}
class StackEmptyException extends Exception
{
public StackEmptyException ()
{
super();
}
public StackEmptyException (String s)
{
super(s);
}
}
The Tester
StackTester.java
/**
* StackTester.java
*
* Some test cases for a stack.
*/
public class StackTester
{
public static void testOne (Stack s)
{
try
{
if (s.size() != 0 || !s.isEmpty())
System.out.println("1: Failed size or isEmpty.");
s.push(1);
s.push(2);
if (s.size() != 2 || s.isEmpty())
System.out.println("2: Failed size or isEmpty.");
if (!(s.pop() == 2))
System.out.println("3: Failed pop");
if (!(s.peek() == 1))
System.out.println("4: Failed peek");
if (!(s.pop() == 1))
System.out.println("5: Failed pop");
if (s.size() != 0 || !s.isEmpty() )
System.out.println("6: Failed size or isEmpty.");
}
catch (StackEmptyException e)
{
System.out.println(e);
}
}
public static void testTwo (Stack s)
{
try
{
for (int i = 0; i < 100; i++)
{
s.push(i);
}
if (s.size() != 100)
System.out.println("7: Failed size.");
for (int i = 99; i >= 0; i--)
{
if (!(s.pop() == i))
{
System.out.println("Failed pop for: " + i);
break;
}
}
}
catch (StackEmptyException e)
{
System.out.println("Failed testTwo.");
System.out.println(e);
}
}
public static void testThree (Stack s)
{
try {
while (!s.isEmpty())
s.pop();
}
catch (StackEmptyException e) {
System.out.println ("Failed empty stack test (popped on a non empty stack threw exception)");
}
try
{
s.pop();
System.out.println("Failed empty stack test.");
}
catch (StackEmptyException e)
{
/* If we get here, we
* passed the previous test.
*/
}
}
public static void main (String args[])
{
Stack s1 = new StackLL();
Stack s2 = new StackLL();
Stack s3 = new StackLL();
testOne(s1);
testTwo(s2);
testThree(s3);
}
}
You have private LinkedList values; in StackLL.
That says "this class has a field called values of type LinkedList". It does not assign an object to values, so when you try to access it, a NullPointerException occurs.
You should be able to fix it by assigning a value to values, i.e.:
private LinkedList values = new LinkedList();
(I don't know if you've learned about generics yet, but if you have, remember to add the type, e.g. LinkedList<Person>.)
Look at the line of code given in the error message (I'm assuming its the return statement in your size() function) and think about the meaning of NullPointerException -- the variable which is null is not yet initialized. Then ask yourself, do I expect this variable to be initialized here? If yes, then ask why isn't it and where should it be initialized? If no, then you have a logic error at the given location.
You aren't ever instantiating a LinkedList object in StackLL. So the first time you try to access it, it blows a NPE.

Categories