Dynamic array based stack - java

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.

Related

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");
}
}

How to add items into an Array Generic Object from the parameter in Java

So, I am creating a generic data structure named "Sack". In this I add items to a sack, grab a random item, see if it's empty, or dump out its contents etc. Also I'm creating it to expand to hold as many items as needed.
Currently, I'm working on the add method and I'm having troubles on my add method, and I am trying to think of a way adding what's in my parameter into the sack.
import java.util.Arrays;
public class Sack<E>
{
public static final int DEFAULT_CAPACITY = 10;
private E [] elementData;
private int size;
#SuppressWarnings("unchecked")
public Sack()
{
elementData = (E[]) new Object[DEFAULT_CAPACITY];
}
#SuppressWarnings("unchecked")
public Sack(int capacity)
{
if(capacity < 0)
{
throw new IllegalArgumentException("capacity " + capacity);
}
this.elementData = (E[]) new Object[capacity];
}
public boolean isEmpty()
{
if(size == 0)
{
return true;
}
else
{
return false;
}
}
public E [] dump()
{
E [] E2 = Arrays.copyOf(elementData, size);
for(int i = 0; i < size; i++)
{
elementData[i] = null;
}
size = 0;
return E2;
}
In this method, I am trying to add item, into my sack. When I run my tests, I am told it's incorrect. If there's a way to improve this.
public void add(E item)
{
elementData[size] = item;
size++;
}
elementData is what I am adding the items into.
Update
I updated my add method to look like this.
public void add(E item)
{
if(size >= elementData.length-1)
{
elementData[size] = item;
size++;
}
}
The message I am now receiving is that add is not working correctly and to check size usage.
You cannot ensure capacity of Java arrays, Javascript can! You can create a new one and copy:
public void add(E element) {
int index = size++;
if(size >= elementData.length-1) {
// it ensures elementData
elementData = java.util.Arrays.copyOf(elementData, size);
}
elementData[index] = element;
}
or skip ensure of array capacity and change the check direction:
public void add(E element) {
if(size < elementData.length-1) {
elementData[size++] = element;
}
// TODO else notice of the unsuccessfull add
}
It sounds like there's a spec for what your Sack is supposed to do that you did not paste.
It also sounds like your add method is supposed to just work, even if the sack is already at capacity.
That means you need to make a new array, copy over all elements, and then replace the array you have in your Sack instance with the new one (because java arrays cannot grow or shrink).
Look at the source of of java's own ArrayList for a hint on how that's done.
So after numerous tries, I give credit to #rockfarkas for solving this. I put in the following code and it solved my add method code.
public void add(E item)
{
int index = size++;
if(size >= elementData.length-1)
{
elementData = Arrays.copyOf(elementData, size);
}
elementData[index] = item;
}
Here's another way of doing this,
public void add(E item)
{
ensureCapacity(size+1);
elementData[size] = item;
size++;
}
This also works, but I would have to modify the ensureCapacity method accurately, which I have.

Double Stack-last elements

I have a homework about making a Double stack, consisting of redStack and blueStack, and have their own operations (e.g redPush, bluePush). But for the pop, it knows the last added element in both stacks, and remove it. My question is how could I make it know the last added elements?
Here's my code:
public T pop() {
if (redCounter > blueCounter) {
redCounter--;
return redStack.pop();
}
if (blueCounter > redCounter) {
blueCounter--;
return blueStack.pop();
}
}
My code here shows removing the last element depending on the counter for each stack. But how can I know the last added one if they are equal to each other? Thanks.
If you must use two stacks for this then I would maintain a third stack lastAdded that pushes a label for the last pushed element. If the last pushed element was red, then push 0, otherwise 1.
Then in pop you check lastAdded for last type of element pushed, and pop from the corresponding stack.
public T pop() {
if (lastAdded.empty()) {
throw Exception();
}
int lastColor = lastAdded.pop();
if (lastColor == 0) {
return redStack.pop();
}
return blueStack.pop();
}
Besides this I would simply use a single stack for all operations, since per your description of the problem the operations you want seem no different then that of a single stack.
Update: With exactly two stacks you would have to make some modifications to the stack itself. Instead of pushing the value itself, push the value + a counter. When popping, pop the element off the stack that has a greater counter value:
class DoubleStack {
// Java 7 has its own pair class
private class Pair<T, U> {
private T first;
private U second;
public Pair(T x, U y) { first = x; second = y; }
public T getKey() { return first; }
public U getValue() { return second; }
}
private Stack<Pair<Integer, Integer>> redStack = new Stack<>(), blueStack = new Stack<>();
private int c = 0;
public boolean empty() {
return redStack.empty() && blueStack.empty();
}
public void pushRed(int x) {
redStack.push(new Pair<>(x, c++));
}
public void pushBlue(int x) {
blueStack.push(new Pair<>(x, c++));
}
public int pop() {
if (empty()) {
return Integer.MAX_VALUE; // throw an exception
}
if (redStack.empty()) {
return popBlue();
}
if (blueStack.empty()) {
return popRed();
}
if (redStack.peek().getValue() > blueStack.peek().getValue()) {
return popRed();
}
return popBlue();
}
private int popRed() {
return redStack.pop().getKey();
}
private int popBlue() {
return blueStack.pop().getKey();
}
};

How to check to see if the top two elements of the stack exists?

I'm working with a Java Stack, and I want to know whether or not if the the stack has at least 2 items on top. I'm limited to just the methods in Stack and can't use things like .add().
My current problem is when the value of an element is 0. I have to deal with both positive, negative, and 0 ints. Here is my code for the method in question:
public static <E> boolean hasTwoElements(Stack<E> stack) {
int temp1 = 0;
int temp2 = 0;
boolean happened = false;
if (!stack.isEmpty()) {
//check if the assignment is success
happened = ((temp1 = (java.lang.Integer) stack.pop()) != 0)
&& ((temp2 = (java.lang.Integer) stack.pop()) != 0);
if (happened) { //if the 2 assignments happened
stack.push((E) new Integer(temp2)); //reverse order b/c popped in order
stack.push((E) new Integer(temp1));
return true;
}
}
return false;
}
To be more specific, I need to know whether an assignment succeeds or not.
If you truly can use only methods that are declared on the Stack class, and not methods inherited from parent class, then do it like this:
public static <E> boolean hasTwoElements(Stack<E> stack) {
if (stack.empty())
return false;
E top = stack.pop();
boolean hasTwo = ! stack.empty();
stack.push(top);
return hasTwo;
}
How about:
public static <E> boolean hasTwoElements(Stack<E> stack) {
return (stack.size() >= 2);
}
See Stack.size()

Beginner Stacks, OutofBoundsException 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;
}

Categories