Reversible iterator - java

public ReversibleIterator iterator();
can anyone help me make this method? ill put up what i have done so far
The ReversibleIterator should behave as follows. The first call to next or previous should return the first or last element of the list, respectively. Subsequent calls to next/previous should return the element that is next/previous with respect to the antecedent call to next/previous. For example, if two calls to next result in Sunday and Monday, then a following call to previous should return Sunday.
public ReversibleIterator<T> iterator() {
PublicLinkedList<T> list = new PublicLinkedList<T>();
PublicNode<T> node = list.head;
while (node.getElement() != null) {
list.add(node.getElement());
node = node.getNext();
}
ReversibleIterator<T> rIter = new ReversibleIterator<T>(list);
return rIter;
}

Java's ListIterator is what you need. The big advantage: It already exists.
You can retrieve it from any list in Java by calling the listIterator() function.

Related

For each loop of Iterator skips first element

For school I had to made a kind of linked list like queue.
My nodes have 3 attributes:
Node left (Node left of the node)
Node right (Node right of the node)
Object item (The object that is stored in the list)
I also have to make the list iterable so implemented that interface.
The problem I have now is that if there are for example 4 items in the list, it only shows 3 of them.
So if for example the list has 4 strings in it, 'a', 'b', 'c' and 'd' the output is:
b
c
d
My hasNext method looks like:
#Override
public boolean hasNext() {
return node.getRight() != null;
}
and my next method looks like:
#Override
public T next() {
node = node.getRight();
Object item = node.getItem();
return (T)item;
}
If I return the item of the node instead of the node on the right I get
a
b
c
as return but that is also not good because it skips the last one. And when you read the API next should return the next value so I guess my next method has to be as it is.
The iterator's methods should be implemented as this:
#Override
public T next() {
Object item = node.getItem();
node = node.getRight();
return (T)item;
}
#Override
public boolean hasNext() {
return node != null;
}
Just think about other iterators. At the first call of next() they return the first element and THEN they move forward to the second. When you are pointing to the last element, next() should return it and move forward (i.e. point to null). To be able to do this, the test inside of hasNext should be on the current item, not on the next, otherwise you could not get the last element.
You probably initialize the node property by setting it to the first node, so a next () call points to the second. Try checking for the first node:
boolean first = true;
#Override public T next() {
if (!first) {
node = node.getRight();
}
else
first = false;
Object item = node.getItem();
return (T)item;
}

How do you construct a JAVA recursive method Dequeue

Firstly, I have a linked list implementation of a Queue where Dequeuing occurs at the Head of the linked list. I have one no-argument no-return public method:
public void recursiveDequeue() {
head = recursiveDequeue(size()-1, head);
}
And a second method:
private Node recursiveDequeue(int index, Node current) {
if (current==null) {
// some code I need to write
}
return current;
}
I cannot for the life of me figure out how to do this. The only thing I can change is the comment that states clearly where I need to write code.
How do you build a recursion method that dequeues from the head but whose calling method already refers to the head? How is that even recursion? I dont even know what this is supposed to do.
Maybe something like the following. I don't know what exactly to do with index, seems superfluous here, but if it is the number of elements to dequeue as suggested in comments:
private Node recursiveDequeue(int index, Node current) {
if (current==null || index==0) {
return null;
}
return recursiveDequeue(index-1,current.next); // for a single-linked list
}
If the only code you are allowed to write is conditional upon the node argument being null then there is no solution because you can't impact a queue with a non-null head.
If the condition is intended to be current != null then it's possible:
if (current != null) {
if (index > 0)
return recursiveDequeue(index - 1, current.getNext());
}
return current;
This will dequeue index items. Given your no argument method calls it with size - 1 it will dequeue all but the last item.

Descending ListNode Iterator Implementation

My goal in this method is to write the implementation for an iterator that iterates through elements of a listNode in descending order. (From the back to the front) I have attached my implementation of the ascending iterator. Any help in the right direction would be appreciated.
public MyDescendingDequeIterator(ListNode<E> back, ListNode<E> front) {
frontOfList = front;
nextToReturn = back;
while (nextToReturn.next != null) {
nextToReturn = nextToReturn.next;
}
}
public boolean hasNext() {
if (nextToReturn == null){
return false;
} else {
ListNode<E> current = frontOfList;
return true;
}
}
public E next() {
ListNode<E> current = frontOfList;
while ( current.next != nextToReturn ) {
current = current.next;
}
nextToReturn = current;
return nextToReturn.data;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
Provided it's a regular ListNode implementation that has only next() method, you'll need to implement the prev() method - the hasNext in that case is quite similar to the one you've implemented already.
The other approach is to hold the start of the list and to iterate each time until next element will be nextToReturn (and then update nextToReturn). This is less desired approach since you'll need to iterate O(m^2) from end to start of list of length m;
UPDATE:
OK, first of all you don't need number of elements, since it's quite opposite to the Iterator idea.
So let's say we have
public MyDescendingDequeIterator(ListNode<E> back, ListNode<E> front) {
frontOfList = front;
nextToReturn = frontOfList;
current = frontOfList;
}
Next thing is than you want to set the nextToReturn = back (now you don't use back at all). And you don't really need two variables, since nextToReturn is the current iterator.
So it transforms to:
public MyDescendingDequeIterator(ListNode<E> back, ListNode<E> front) {
frontOfList = front;
nextToReturn = back;
}
Now let's look on the next() method
As I said you don't need an indexed for here, since you've got frontOfList that has a next attribute.
So it could be:
public E next() {
ListNode<E> current = frontOfList;
while ( current.next != nextToReturn ) {
current = current.next;
}
nextToReturn = current;
return nextToReturn.data;
}
hasNext implementation should be straightforward from here. Just pay attention that according to the good coding standards the method that starts with is or has rarely changes the state of the object.
Note, that I also omit possible null checks here and other possible specific checks as is just an example of direction.
UPDATE 2:
As I think of it now, you don't need the second parameter in the constructor either, just this:
public MyDescendingDequeIterator(ListNode<E> front) {
frontOfList = front;
nextToReturn = front;
// calculate back here instead of get it as param
while ( nextToReturn.next != null) {
nextToReturn = nextToReturn.next;
}
}
UPDATE 3:
Look, it won't help to just start writing some code and expect it to work, you should sit down first and start drawing the boxes with the arrows on the piece of paper and then try to understand what each function should do.
As I said before, your hasNext() method has a bug and incorrect in general. Why do you check the null? You move from back to front, do you have a null at some place at the front? What do you need the current object for. What does it do?
The next() method should check also if you're already at the first element. Otherwise it will (and it does ) cause NullPointerException at the last element.
Try to debug first, or at least add some printouts, it helps to understand where the bug is. But first you should build the algorythm, only then start coding it, not vice versa.

Deduplicate Iterator

Implement an iterator(Generic) which skips next element if it is equal to last printed element.
e.g : AAABBCCCCD
On complete iteration will print ABCD.
Below is my attempt. Please suggest if it can be done in a better way.
import java.util.Iterator;
public class DeDupIterator<E> implements Iterator<E> {
E next = null;
Iterator<E> itr;
public DeDupIterator(Iterator<E> iter) {
itr = iter;
next = itr.next();
}
#Override
public boolean hasNext() {
if(itr.hasNext())
if (next != null) {
return true;
}
return false;
}
#Override
public E next() {
E item=null;
while (itr.hasNext()) {
item = (E) itr.next();
if (!item.equals(next)) {
E temp = next;
next = item;
return temp;
}
}
next = item;
return next;
}
#Override
public void remove() {
itr.remove();
}
}
It's hard to answer this question without actually writing the code for you.
I'll just focus on main issues with this code:
it doesn't work for empty collections, because it calls itr.next() unconditionally in the constructor, which leads to an exception
it doesn't work for a single element collections, because hasNext() returns false instead of true - this is because you call itr.next() in the constructor and then in hasNext() you first check itr.hasNext()
remove() is completely wrong, because itr.next() was called earlier
it should throw NoSuchElementException in next() if there is no element to return, but it doesn't
How to fix it?
I would start by removing itr.next() from constructor as it's messing many things up.
Then you have to somehow distinguish between two cases: when itr.next() was called in advance or not. E.g. add a boolean field to facilitate that.
You will have to call itr.next() in advance if hasNext() is called.
Also you should be prepared that itr.next() returns null as a completely valid value that can be stored in a collection. You should not rely on next to be not null. For this reason you should have one more boolean that determines whether your next field actually holds a value or is empty.
The remove() method should probably remove all the duplicates and not only one element. If you find it too demanding to implement you can always throw UnsupportedOperationException. If you decide to implement it, remember to throw IllegalStateException if next() has not yet been called, or remove() has already been called after the last next() call
This should be enough for you to get the right solution yourself. Good luck.

Java : Implementing iterator for user-created HashSet class. Semantics of next() and hasNext()?

taking a java class and we have to design our own HashSet class. (not using the JAVA apis)
I have to implement and iterator for this, and I am confused about the semantics of using one.
Not sure if a call should be allowed to be made to Next() which will move the index of the iterator, or if a user must absolutely use next() in conjunction with a hasNext() loop which will move the index.
For instance, what would happen if the user had several consecutives calls to next() without hasNext() ?
Thanks for everyone's help!
public class HashWordSet implements WordSet {
private int size;
private Node[] buckets = new Node[8];
//above is only provided for mention of variables
private class Node {
Word value;
Node next = null;
public Node(Word word) {value = word;}
public String toString() {return value.toString();}
}
class WordIterator implements Iterator<Word> {
private Node next;
private int index = 0;
public Word next() {
Node element = next;
if (element == null)
throw new NoSuchElementException();
if ((next = element.next) == null) {
Node[] temp = buckets;
while (index < temp.length && (next = temp[index++]) == null)
;
}
return element.value;
}
public boolean hasNext() {
return (next != null);
}
The Javadoc specifies that if next is called and there isn't a next element, you must throw a NoSuchElementException. That said, you should not assume that hasNext is always called before next -- or that hasNext is called only once!
The typical way to do this for a hash table is that
hasNext advances through the hash table if it's not already pointing to a valid element.
next calls hasNext as its first step, and after it's done returning the next element, increments to the next position in the hash table (without checking to see if there is an element in that position).
Just follow the API as shown here http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Iterator.html
If a user calls next() and there are no more elements, you throw a NoSuchElementException.
You absolutely should be able to use an iterator by only calling next(), assuming that it's in a valid state for you to do that. Checking hasNext() on each iteration is the idiomatic way to do things, but it is not required and you should not rely on callers doing this.
In fact, hasNext() should be idempotent and essentially should not change any state of your iterator at all. Since it doesn't change the state, by definition it can't make a different whether it was previously called or not.
So basically yes - every time next() is called, you should return the "current" element of your iterator, and then advance the "pointer" (for whatever those concepts mean in your implementation).
What would happen if the user had several consecutives calls to next() without hasNext()?
If there were sufficient elements left to iterate over, he would get successive elements returned with each call to next(). If he thinks he knows better, and calls next() after reaching the end of the iterator (i.e. when hasNext() would have returned false), then as per the Javadocs you should throw a NoSuchElementException.

Categories

Resources