I understand how stacks work, but I have to write methods for push, pop and peek and then implement them in a driver class. This is where it gets confusing. Here is my Stack class:
public class Stack implements StackInterface
{
private final int ARRAY_SIZE = 9;
private String[] movies = new String[ARRAY_SIZE]; // Hold movie titles
private int top = 0;
/**
* Constructor
* #param moviesIn
*/
public Stack(String[] moviesIn)
{
movies = moviesIn;
}
/**
* Test for full stack
*/
public void push(String moviesIn)
{
if (top >= movies.length)
System.out.println("ERROR: Stack is full");
top++;
movies[top] = moviesIn;
}
/**
* Test for empty stack
*/
public String pop()
{
if (top == 0) {
System.out.println("ERROR: Stack is empty");
return " ";
}
top--;
return movies[top];
}
public void peek()
{
// ???
}
}
Here is what I have in my main() method so far:
public static void main(String[] args)
{
String[] movies = {"Amour", "*Argo", "Beasts of the Southern Wild", "Django Unchained", "Les Misérables", "Life of Pi", "Lincoln", "Silver Linings Playbook", "Zero Dark Thirty"};
Stack oscarStack = new Stack(movies);
oscarStack.push(movies);
}
I thought I could just pass an object to the stack, but it doesn't seem to work that way. So how do I push the oscarStack object onto the stack? Or do I have to push each string individually? In continuing my online research, it seems a stack constructor can only create an empty stack. Is this why I cannot pass an object argument?
In main, you're placing all of your elements into the backing array implicitly without any push operations. What you'd likely want to do is iterate over the movies you want to push, then push them in.
Two changes should be made:
Change your Stack object to no longer accept an array of Strings. This is confusing and unnecessary as all of the initialization is done on construction.
There are two bugs with your push:
You don't account for the case in which the array is empty. Switch around your incrementation of top, or use movies[top++].
You don't actually prevent code execution if the array is full. You'll get ArrayIndexOutOfBoundsException if you try to run with what you've got.
public static void main(String[] args) {
String[] movies = {"Amour", "*Argo", "Beasts of the Southern Wild", "Django Unchained", "Les Misérables", "Life of Pi", "Lincoln", "Silver Linings Playbook", "Zero Dark Thirty"};
Stack oscarStack = new Stack();
for(String movie : movies) {
oscarStack.push(movie);
}
}
You will have to push each element of the array onto the stack:
for (String movie : movies) {
oscarStack.push(movie);
}
Alternatively, you could write a "pushAll" method in your Stack class that accepts a string array and basically does the same thing.
However, you seem to already be setting the movies array in the constructor, so I don't see the purpose of the call to push. Perhaps you can explain further.
P.S. You seem to have a bug in your push method:
public void push(String moviesIn)
{
if (top >= movies.length)
System.out.println("ERROR: Stack is full");
top++;
movies[top] = moviesIn;
}
With this code, there's no way that movies[0] will ever be assigned a value.
The push method expects a string as an argument and not an array of strings so you can either change the push method to accept string arrays as argument or pass one string at a time to your current push method.
Also you are not pushing oscarStack object and if you want to push any object the again the method signature should support that.
Apart from the answers given here, also remember to null the reference that was popped from the stack.
Here is a quote from the book 'Effective Java '
Generally speaking, whenever a class manages its own memory, the
programmer should be alert for memory leaks. Whenever an element is
freed, any object references contained in the element should be nulled
out.
A sample copied from the book:
public Object pop() {
if (size==0) throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}
If you want to use Stack data structure and you don't want to incur the cost of Synchronization then you can use Dequeue. Stack class available in Java extends Vector.
Deque<Integer> q=new LinkedList<Integer>();
q.offerFirst(Integer.SIZE);
q.offerFirst(Integer.SIZE);
q.pollFirst();
This is the most efficient stack implementation that is available in Java collection framework.
You should probably initialize your variable as top=-1.Note that I have not initialized a constructor for this class Stack since its not compulsory to do so.If no user-defined constructor is provided for a class, compiler initializes member variables to its default values.
1.numeric data types are set to 0.
2.char data types are set to null character(‘\0’).
3.reference variables are set to null.
Here is how the full code should be implemented:-
public static void main(String[] args)
{
String[] movies = {"Amour", "*Argo", "Beasts of the Southern Wild", "Django Unchained", "Les Misérables", "Life of Pi", "Lincoln", "Silver Linings Playbook", "Zero Dark Thirty"};
Stack oscarStack = new Stack();
for (String movie:movies){
oscarStack.push(movie);
}
}
public class Stack implements StackInterface
{
private final int ARRAY_SIZE = MAX_SIZE;
private String[] movies = new String[ARRAY_SIZE]; // Hold movie titles
private int top = -1;
/**
* Test for full stack
*/
public void push(String moviesIn)
{
if (top >= movies.length)
System.out.println("ERROR: Stack is full");
return;
top++;
movies[top] = moviesIn;
}
/**
* Test for empty stack
*/
public String pop()
{
if (top == -1) {
System.out.println("ERROR: Stack is empty");
return " ";
}
top--;
return movies[top];
}
public void peek()
{
if(top==-1){
System.out.println("ERROR: Stack is empty");
return " ";
}
else{
return(movies[top]);
} }}
Related
For an assignment, I must create a queue using stacks, but I am not sure what I am doing wrong with this code. I created a primary, alternative, and temporary stack. Every push, I want the value to be added into alternative, and everything currently in primary to be popped into temporary. Then, from temporary, I want all values to be popped into alternative, then change variables so that alternative is the main stack. Now, when I run this to test multiple values entered into the stack, I get an infinite loop with nothing output. I've been stuck on this for a while now so I was hoping I could get some help here. Here's the code.
Stack<Integer> mainStack = new Stack<Integer>();
Stack<Integer> altStack = new Stack<Integer>();
Stack<Integer> tmpStack = new Stack<Integer>();
public void push(int x) {
altStack.add(x);
while (mainStack.empty() == false){
tmpStack.push(mainStack.pop());
}
while(tmpStack.empty() == false) {
altStack.push(tmpStack.pop());
}
mainStack = altStack;
altStack = tmpStack;
}
public int pop() {
return mainStack.pop();
}
public int peek() {
return mainStack.peek();
}
public boolean empty() {
return mainStack.empty();
}
So your idea seems to be to push everything from one stack into another to reverse the order of the elements. I cannot see how you get an infinite loop because you always pop and do it until empty. But two queues are enough to solve this using your idea:
Stack<Integer> mainStack = new Stack<>(); // elements pop in correct order
// the fake queue so to speak
public void push(int x) {
Stack<Integer> stack = new Stack<>(); // temporary stack
// reverse main stack
while (!mainStack.empty())
stack.push(mainStack.pop());
// add x first (at the bottom) of the now empty main stack
mainStack.push(x);
// add the rest of the elements to main stack (preserving original order,
// by reversing the elements again)
while (!stack.empty())
mainStack.push(stack.pop());
}
My queue uses a stack hence I have two stacks.. s1 that accepts the add, then all of its items get moved into s2 which makes s2 my queue.
(no use of arrays..)
here is my implementation but when I test it, my remove unit test fails.
public class Queue
{
private Stack s1;
private Stack s2;
private int size;
public Queue()
{
//arbitrary sized.
s1 = new Stack();
s2 = new Stack();
size = 0;
}
public void insert(Object o)
{
//add object into s1.
s1.push(o);
size++;
}
//delete from queue
public Object remove()
{
int n = 0; ... arbitrary size n. //size not specified
for(int i = 1; i <= n ; i++)
{
//push all elements in s1 into s2
s2.insert(s1.pop());
}
//decrease the size
size--;
return s2.pop;
}
public Object peekFront()
{
s2.push(s1.pop());
return s2.peek();
}
}
TEST
import org.junit.Assert;
import static org.junit.Assert.*;
import org.junit.Test;
public class QueueTest
{
protected Queue q;
public QueueTest()
{
q = new Queue();
}
atTest
public void testRemove()
{
assertTrue(q.isEmpty()); -- passes
q.insert(10);
q.insert(11);
q.insert(12);
q.insert(23);
//remove
assertEquals(10, q.remove()); --- fails
}
public void testPeekFront()
{
q.insert(80);
q.insert(90);
q.insert(57);
assertEquals(20,q.peekFront());
}
}
Please can you put me in the right direction on why my public Object remove is not functioning correctly...
For example when I try to remove 23? My test passes but when I test for 10 which actually should be, then it fails.
Here is the complete code..... for both the class and the test...
I think you may be providing a static value for n. As the value n , will change dynamically, please make sure you are giving n=s1.size() [or any custom function to calculate size]. Please provide the complete code.
Assumed Fixes:
1. You are popping out all elements from s1 , during remove. Making it(s1) empty stack. So you have to fill it back by popping the values from s2 in the remove function itself. As fabian mentioned in the next answer use a helper method for transfering of elements from 1 stack to another.
2.In remove() method, store s1.pop() to a temp variable and remove all elements in s2. return temp variable. Other wise s2 will keep on growing.
3. set n = s1.size();
4. return s1.pop();
For the method to work you cannot simply hardcode the size. Furthermore you have to move the elements back to the original stack before the next insertion, or the order becomes wrong. I recommend transfering the objects in a helper method to avoid code duplication:
private static void transfer(Stack source, Stack target) {
while (!source.isEmpty()) {
target.push(source.pop());
}
}
I recommend moving the elements lazily to avoid unnecessary operations for repeated insert or repeated remove operations:
public void insert(Object o) {
// lazily transfer values back
transfer(s2, s1);
//add object into s1.
s1.push(o);
size++;
}
//delete from queue
public Object remove() {
if (s1.isEmpty() && s2.isEmpty()) {
return null; // alternative: throw exception
}
transfer(s1, s2);
//decrease the size
size--;
return s2.pop();
}
public Object peekFront() {
if (s1.isEmpty() && s2.isEmpty()) {
return null; // alternative: throw exception
}
transfer(s1, s2);
return s2.peek();
}
Alternatively you could simply transfer the values back to s1 in the remove method, which would make it a bit simpler to implement additional operations, however it would also make some operation sequences less efficient. (You also still need to fix peekFront()):
//delete from queue
public Object remove() {
if (s1.isEmpty() && s2.isEmpty()) {
return null; // alternative: throw exception
}
transfer(s1, s2);
//decrease the size
size--;
Object result = s2.pop();
transfer(s2, s1);
return result;
}
I have a generic LinkedStack class with a LinkedStack reversed method
It creates a new LinkedStack say newLinkedstack and pushes items from the current stack by popping them. So at the end of the operation the current stack is left empty and newLinkedStack contains the same items/elements that were in "this" stack only in reverse order.
My code compiles but when I create and fill up a stack and then print out the contents,
I only get one result.
public LinkedStack<T> rev()
{
LinkedStack<T> revStack=new LinkedStack<T>();
//final int SIZE=this.size();
while(!(this.empty)){//for(int i=0;i<SIZE;i++)
{
revStack.push(this.pop());
}
return revStack;
}
For example
LinkedStack<String> newLS = new LinkedStack<String>();
newLS.push("noid");
newLS.push("enilec");
newLS.push("River");
newLS.push("Healing");
newLS.push("Pain");
and newLS.rev() returns Pain instead of a reversed stack
UPDATE
Here's my pop method
public T pop()
{
T element=peek();
top=top.next;
return element;
}
I have two push methods this one moves every element from input stack to current stack leaving input stack from argument empty
public void push(LinkedStack<T> stack){
//int SZE = stack.size();
while(!(stack.empty())){//formally for(int i=0;i<SZE;i++){
this.push(stack.pop());}}
Here's my other push method
public void push(T element)
{
top=new Node<T>(item,top);
}
I'm not sure where LinkedStack came from, but it seems that the bug is being caused by that class's implementation.
You'll have to post more source code if you want more specific help.
Ok I was recently asked this in an interview, and I am intrigued. Basically I have a stack with a certain set of values, I want to pass the stack object in a function and return the value at certain index. The catch here is that after the function is complete, I need the stack unmodified; which is tricky because Java passes reference by value for objects. I am curious if there is purely a java way to do using push(), pop(), peek(), isempty() and primitive data type. I am against copying the elements into an array or string. Currently the cleanest I have got is using clone, find the code below:
import java.util.Stack;
public class helloWorld {
public int getStackElement( Stack<Integer> stack, int index ){
int foundValue=null;//save the value that needs to be returned
int position=0; //counter to match the index
Stack<Integer> altStack = (Stack<Integer>) stack.clone();//the clone of the original stack
while(position<index)
{
System.out.println(altStack.pop());
position++;
}
foundValue=altStack.peek();
return foundValue;
}
public static void main(String args[]){
Stack<Integer> stack = new Stack<Integer>();
stack.push(10);
stack.push(20);
stack.push(30);
stack.push(40);
stack.push(50);
stack.push(60);
helloWorld obj= new helloWorld();
System.out.println("value is-"+obj.getStackElement(stack,4));
System.out.println("stack is "+stack);
}
}
I understand that cloning is also copying, but that's the basic flaw I am aiming to remove. Stripped down I am asking if I would be actually be able to pass the stack's value instead of passing the value of its reference.
Thanks in advance.
int position =5;
Integer result = stack.get(position);
Java Doc here
If you cannot use another stack, you can cheat and abuse a local variable on the call stack for the same purpose by making a recursive method:
public static <T> T getStackElement(Stack<T> stack, int index) {
if (index == 0) {
return stack.peek();
}
T x = stack.pop();
try {
return getStackElement(stack, index - 1);
} finally {
stack.push(x);
}
}
Question :
b) A Stack is a last-in first-out (LIFO) data structure. Write a Java class
Stacklnt that stores a stack of integers using an alray as its private data
structure. A Stacklnt has:
A maximum size, which is set when a Stacklnt object is created.
An exception should be thrown if the size is outside the range 10 to .
1000
A method push, to add a value to the top of the stack. An exception
should be thrown if the stack is full when push is called.
A method pop, to remove and return the value at the top of the stack.
An exception should be thrown if the stack is empty when pop is
called.
c) Write some example code to show how your class Stacklnt from part (b)
should be used. Include examples of normal usage and for all cases when
exceptions are thrown.
Ok so basically this is a question im trying to solve and would really really appreciate some help.
exceptions are in this form
// Throw an exception!
public T pop() throws EmptyStackException
{
if (contents.size() == 0)
{ throw new EmptyStackException(); }
else
{ return contents.remove(0); }
}
me so far :
public class Stack {
private int top;
private int[] storage;
Stack(int capacity) {
if (capacity <= 0)
throw new IllegalArgumentException(
"Stack's capacity must be positive");
storage = new int[capacity];
top = -1;
}
void push(int value) {
if (top == storage.length)
throw new StackException("Stack's underlying storage is overflow");
top++;
storage[top] = value;
}
int peek() {
if (top == -1)
throw new StackException("Stack is empty");
return storage[top];
}
}
You're trying to do the whole program at once, which is a bit difficult because there could be many trivial syntax errors, and any ONE of them will cause it to not compile.
So, the recommendation is to take baby steps - you'll probably hear this a lot. It goes like this (assuming you haven't written any code yet):
1) Edit your StackInt.java file so that it only contains the following:
class StackInt {
}
2) Compile it.
2a) If it doesn't compile correctly, fix those errors FIRST before adding new code.
3) Add a small amount of new code. Say, a main() method. Your class now looks like this:
class StackInt {
public static void main(String[] args) {
System.out.println("hello world!");
}
}
4) Compile it. Then run it. If it doesn't compile, fix those errors before continuing. If it compiles, then run it. You should see it print out "hello world!". This tells you it was run successfully. If there's no output, then you know somethings wrong, and you'll have to fix that before continuing.
In this way, you take "baby steps" - you add just a small amount of code each time, and then compile it and run it to make sure it works the way you expect.
Doing programs this way has been really helpful to me. You can work on one method at a time, instead of typing ALL of them in and wondering where it fails. I recommend it.
Edit:
Since you already have code written, you could adapt this "baby steps" approach by commenting out most of your code so that you don't waste it. Use /* and */ to comment out entire sections - this way the compiler ignores it and you can go about trying out one piece at a time. It looks like this:
class StackInt {
/*
this is "commented out"
push(int number) {
}
*/
public static void main(String[] args) {
System.out.println("hello world!");
}
}
Hope this helps.
read Fundamentals of OOP and Data Structures in Java - Richard Wiener
Chapter 11 is all about stacks and queues
As an answer to your last comment to your question: your syntax is not bad. I cleaned your code up a bit and, once you've implemented the StackException class and the pop method, it should compile correct:
public class Stack {
private int top;
private int[] storage;
public Stack(int capacity) {
if (capacity <= 0) {
throw new IllegalArgumentException(
"Stack's capacity must be positive");
}
top = -1;
storage = new int[capacity];
}
public void push(int value) {
if (top == storage.length) {
throw new StackException("Stack's underlying storage is overflow");
}
top++;
storage[top] = value;
}
public int peek() {
if (top == -1) {
throw new StackException("Stack is empty");
}
return storage[top];
}
public int pop() {
// TODO
}
}
Here's what you should do:
Create a class named Stacklnt**.
Use an array of integers int[] as an instance variable.
Use the constructor of the class to initiate the array with a given size as the constructor's parameter. You have to check that this size is in the range (10 to 1000)
make the two instance methods push and pop. You can use an integer variable as a pointer to the current array position, so you increase it when push is called, and you decrease it when pop is called. You have to make sure this pointer doesn't exceed the limits (i.e. doesn't go lower than zero, and doesn't go higher than the size).
Read over your question once more and look for all of the things you have not done.
you have not put in the method pop
you have not followed the example of exceptions given by the sample pop()
you have not check for range properly
you have not written a main method which instantiates a stack and tests it