First of all, I apologise if this is a really obvious question or if I'm not looking at it correctly.
I've been instructed to "extend the stack to be dynamic". I've been given specific instructions on how to do this, namely:
Make a new array tmp of twice the size of the current array
Copy all elements the current array (called S in the lecture notes) into tmp
Set S = tmp;
The block of code which should do this is to be placed into the push() method, replacing the exception throw section.
The problem is, I have no idea what kind of array I should be using (generics have only recently introduced to me and I don't quite understand them as much as I think I should).
Is there something obvious I'm missing or do I just not understand this properly?
I didn't write the majority of this code, only the pop(), push() and top() methods.
public class ArrayStack<E> implements Stack<E> {
private E[] S;
private int top;
private int capacity;
private static int DEFAULT_SIZE = 100;
public ArrayStack(int size){
capacity = size;
S = (E[]) new Object[size];
top = -1;
}
public ArrayStack(){
this(DEFAULT_SIZE);
}
public E pop() throws StackException{
if(isEmpty())
throw new StackException("stack is empty");
return S[top--];
}
public void push(E e) throws StackException{
if (size() == capacity)
throw new StackException("Stack is full");
S[++top] = e;
}
public E top() throws StackException{
if(isEmpty())
throw new StackException("Stack is empty");
return S[top];
}
Looking at your code, it appears that the array should be of E objects.
Using Java Generics, you can create this array with (E[]) new Object[2 * initial_size]
The instructions want you to look at the code segment below in push
if (size() == capacity)
throw new StackException("Stack is full");
and without giving too much away as this is an assignment to do
if (size() == capacity)
Make a new array tmp of twice the size of the current array
Copy all elements the current array (called S in the lecture notes) into tmp
S = tmp;
Related
I wrote this code of stacks using a linked list but I am having a problem with the code it prints the letters in reverse order without creating a function to display the letters in reverse order
class SimpleLinkedListStack2 implements SimpleStack ,Iterable {
static class ListNode<T> {
public T value;
public ListNode<T> next;
public ListNode(T value, ListNode<T> next) {
this.value = value;
this.next = next;
}
}
private ListNode<T> head = null;
private int count = 0;
public Iterator<T> iterator() {
return new Iterator<T>() {
private ListNode<T> next = head;
#Override
public boolean hasNext() {
return next != null;
}
#Override
public T next() {
if (next == null)
throw new NoSuchElementException();
T value = next.value;
next = next.next;
return value;
}
};
}
#Override
public void push(T value) {
head = new ListNode<>(value, head);
count++;
}
#Override
public T pop() throws Exception {
if (count == 0) {
throw new Exception("Stack is empty");
}
T value = head.value;
head = head.next;
count--;
return value;
}
#Override
public T peek() throws Exception {
if (count == 0) {
throw new Exception("Stack is empty");
}
return head.value;
}
}
this is the main class
public class main {
public static void main(String[] args) {
SimpleLinkedListStack2 <String>stack2= new SimpleLinkedListStack2<>();
stack2.push("a");
stack2.push("b");
stack2.push("c");
stack2.push("d");
stack2.push("e");
for (String letters : stack2){
System.out.println(letters);
}
}
}
the out but is
e
d
c
b
a
because I need to make a function to display the letters in reverse order in the class SimpleLinkedListStack2
Just walk through your code:
stack2.push("a");
This changes your stack's head from null to a node that has no next and whose value is "a". Your stack is now: -> ["a", -> null], where -> is 'pointing at object'.
stack2.push("b");
And now your stack is -> ["b", -> ["a", -> null]]: You create a new ListNode object for "b", and update its 'next' pointer to be what head was, and then head points at this newly created thing.
Thus, of course, if you then iterate through it, you get the last thing you added ("b" here), first.
Hence, your code pritns e d c b a - it's what you put in the list, in reverse order, because that's what you programmed, and that's what stacks are (they are 'Last in, First Out' - the last thing you put it is the e, and that's the first thing that comes out, as per the design!
But I want to print in the same order I put the items in!
This is a so-called 'singly linked list', meaning, any given LinkedNode knows its next node, but does not know its previous node. You cannot in-place reverse-walk-through a singly linked list - what you want is not possible without drastic steps.
For example, you could make an entirely new stack, just by iterating through this stack, which naturally ends up with the newly created stack being the exact reverse of the original. And then print that reversed stack, and then toss it away (java is garbage collected; that part happens automatically). There is no 'easy' solution / no solution that takes no memory. You could also just build the string out, and then reverse that instead.
Perhaps that's the point of this homework exercise, to make you think about how these LinkedNode objects relate to each other in memory. Get out a pad of paper and go sketch it out. Boxes and arrows. You'll figure it out.
package java.util;
public
class Stack<E> extends Vector<E> {
public Stack() {
}
public E push(E item) {
addElement(item);
return item;
}
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
public synchronized int search(Object o) {
int i = lastIndexOf(o);
if (i >= 0) {
return size() - i;
}
return -1;
}
private static final long serialVersionUID = 1224463164541339165L;
}
Above is the java source code for stack.
I realized that it is only emulating a stack and not a real one.So my questions are
Am I right in saying that this is just an imitation of Stack and not the real one?
If I can say the above and I want to build it from scratch,how would I do it?(arrays of fixed size or arraylist which in turn uses list(single/double linked)?)
There is no "real Stack", a stack is just an idea, a so-called abstract data type. It supports two operations, push and pop, and the order of elements is defined to be last-in first-out (LIFO). In addition to java.util.Stack (based on Vector, which is array-based), you also have java.util.LinkedList (a doubly-linked list), which also supports stack operations, so it's also a stack as much as the other one.. There are several other implementations, for example all implementations of java.util.Deque.
You can do it from scratch in a number of ways, each has their own trade-offs. Your question is not defined enough for a good answer.
My problem is this: I have an iterator class which is supposed to iterate through elements in a given data structure, <E> let's say, but what I have managed to accomplish is that when I pass in the data structure it will iterate the data structure itself.
ie. DynamicIterator it = new DynamicIterator(da);
say da is an array the output will be [1,2,3,4,5,6] instead of 1,2,3,4,5,6
My issue is, more than anything, understanding the generally accepted practice for dealing with this more than the issue itself.
edit for code:
public class X<E>
{
private final E[] rray;
private int currentIndex = 0;
public X(E... a)
{
//if the incoming array is null, don't start
if(a == null)
{
System.out.println("Array is null");
System.exit(1);
}
//set the temp array (rray) to the incoming array (a)
this.rray = a;
}
//hasNext element?
public boolean hasNext()
{
return rray.length > currentIndex;
}
//next element (depends on hasNext())
public E next()
{
if (!hasNext())
{
System.out.println("Element doesn't exist, done");
System.exit(1);
}
return rray[currentIndex++];
}
//return array
public E[] access()
{
return rray;
}
}
You won't be able to do this with a completely generic parameter <E> - how would you iterate through a Throwable, for example? What your class X does at the moment is accept any number of objects in its constructor, and then simply returns each of those objects in turn.
If you restricted the bounds of the objects passed in to implement e.g. Iterable, then you can actually start to "look inside" them and return their contents:
public class X<E> {
private final Iterator<E> it;
public X(Iterable<E> a) {
it = a.iterator();
}
public boolean hasNext() {
return it.hasNext();
}
public E next() {
return it.next();
}
}
Although this doesn't really accomplish anything different to just using a.iterator() directly instead of an instance of X...
I have to create a method peek MidElement , so as return the middle element of the stack .
So do I have to use an ArrayList, or TORTOISE-HARE algo .
The following is my Class , which has a method named peekMidElement.
How do I reference Size() to the ArrayList .
When I compile the following , I am getting IndexOutOFBoundsExcption at ArrayList.RangeCheck(UnknownSource) & at ArrayList.get(UnknownSource)
public class SortableStack<E extends Comparable<E>> implements ISortableStack<E> {
private int N;
private Node first;
private ArrayList<E> listOne = new ArrayList<E>();
/* I have to reference the Stack to array list
which I am going use for finding the size of the stack */
public boolean isEmpty() {
return first == null;
}
public int size() {
return N;
}
public E peekMidElement() {
if(listOne.size() <= 0){
throw new EmptyStackException();
}
return listOne.get(listOne.size()/2);
}
I cannot see how the code snippet you gave can throw an IndexOutOfBoundsExcption at the point you have indicated. I conclude that:
the code snippet is not the actual code (e.g. it has been spliced together from a larger class, leaving out some crucial details), or
the exception is not thrown at the place you indicated, or
... this class (which is not thread-safe) is being used in a multi-threaded application without adequate synchronization. The scenario is that some other thread deletes a bunch of elements from listOne at exactly the wrong moment. This unlikely, and if it was the cause, the failure would only occur very occasionally.
For my data structures class our homework is to create a generic heap ADT. In the siftUp() method I need to do comparison and if the parent is smaller I need to do a swap. The problem I am having is that the comparison operators are not valid on generic types. I believe I need to use the Comparable interface but from what I read it’s not a good idea to use with Arrays. I have also search this site and I have found good information that relates to this post none of them helped me find the solution
I removed some of the code that wasn’t relevant
Thanks
public class HeapQueue<E> implements Cloneable {
private int highest;
private Integer manyItems;
private E[] data;
public HeapQueue(int a_highest) {
data = (E[]) new Object[10];
highest = a_highest;
}
public void add(E item, int priority) {
// check to see is priority value is within range
if(priority < 0 || priority > highest) {
throw new IllegalArgumentException
("Priority value is out of range: " + priority);
}
// increase the heaps capacity if array is out of space
if(manyItems == data.length)
ensureCapacity();
manyItems++;
data[manyItems - 1] = item;
siftUp(manyItems - 1);
}
private void siftUp(int nodeIndex) {
int parentIndex;
E tmp;
if (nodeIndex != 0) {
parentIndex = parent(nodeIndex);
if (data[parentIndex] < data[nodeIndex]) { <-- problem ****
tmp = data[parentIndex];
data[parentIndex] = data[nodeIndex];
data[nodeIndex] = tmp;
siftUp(parentIndex);
}
}
}
private int parent(int nodeIndex) {
return (nodeIndex - 1) / 2;
}
}
Technically you're using the comparable interface on on item, not an array. One item in the array specifically. I think the best solution here is to accept, in the constructor, a Comparator that the user can pass to compare his generic objects.
Comparator<E> comparator;
public HeapQueue(int a_highest, Comparator<E> compare)
{
this.comparator = compare;
Then, you would store that comparator in a member function and use
if (comparator.compare(data[parentIndex],data[nodeIndex]) < 0)
In place of the less than operator.
If I am reading this right, E simply needs to extend Comparable and then your problem line becomes...
if (data[parentIndex].compareTo(ata[nodeIndex]) < 0)
This is not breaking any bet-practice rules that I know of.