Using compartor/Comparable while making Queue to track minimum elements - java

I have been trying to implement a Queue using 2 stacks and was able to implement enqueue and dequeue operation correctly. Now i tried implementing getMin in it and got into a bit of problem.
Theory
In theory, to implement a getMin operation, we store two values in stack- The value and minimum till now. So we will be storing these values in this way- {7, 5, 9, 2, 1} ==> {(7,7), (5,5), (9,5), (2,2), (1,1)}. Now if we try to insert 0, first we will check if 0 is less than current min. If true then we will insert it as (0,0) else (0, last_min_value).
My Approach
I created a class name Element like this
class Element<T>{
T element;
T min;
Element(T element, T min){
this.element = element;
this.min = min;
}
}
My Problem
Well code doesn't compile or better to say I don't understand the concept of compareTo at all, when should i use it. I believe i can understand it in a better way, if i directly use it in my program rather than doing some dummy question
import java.util.Stack;
import java.util.LinkedList;
import java.util.Comparator;
class Element<T>{
T element;
T min;
Element(T element, T min){
this.element = element;
this.min = min;
}
}
class MyQueue<T>{
Stack <Element<T>>s_old;
Stack <Element<T>>s_new;
MyQueue(){
s_old = new Stack<Element<T>>();
s_new = new Stack<Element<T>>();
}
void enqueue(T ele){
if(s_old.empty())
s_old.push(new Element<T>(ele,ele));
else{
if(ele.compareTo(s_old.peek().min) < 0) //problem occurs here
s_old.push(new Element<T>(ele, ele));
else
s_old.push(new Element<T>(ele, s_old.peek().min));
}
}
T deque(){
if(s_new.empty()){
while(!s_old.empty()){
s_new.push(s_old.pop());
}
}
return s_new.pop().element;
}
}
class QueueMain{
public static void main(String args[]){
MyQueue <Integer>q = new MyQueue<Integer>();
q.enqueue(1);
q.enqueue(2);
//System.out.println(q.s_old);
System.out.println(q.deque());
}
}

The problem is quite simple:
In java we have 2 ways to compare an object.
The compared class can either implement the Comparable Interface or use a Comparator.
Here is how you can make the above code work with the Comparable interface:
Comparable
class Element<T extends Comparable<T>> implements Comparable<Element<T>>
{
T element;
T min;
Element(T element, T min)
{
this.element = element;
this.min = min;
}
#Override
public int compareTo(Element<T> ele)
{
int elementCompareResult = ele.element.compareTo(element);
if (elementCompareResult == 0){
// element is the same, Compare by min
return min.compareTo(ele.min);
}
return elementCompareResult;
}
}
Notice how I demand that T will extend Comparable himself, otherwise I would have no way of compering it.
Edit:
Also, the myQueue class looks like this now:
class MyQueue<T extends Comparable<T>>
Comperator
Now lets say I dont want to ask for a T that implements comparable.
I could ask for a Comparator in the constructor like so:
class MyQueue<T>
{
Stack<Element<T>> s_old;
Stack<Element<T>> s_new;
Comparator<T> comparator;
MyQueue(Comparator<T> comparator)
{
s_old = new Stack<Element<T>>();
s_new = new Stack<Element<T>>();
this.comparator = comparator;
}
void enqueue(T ele)
{
if (s_old.empty())
{
s_old.push(new Element<T>(ele, ele));
}
else
{
if (comparator.compare(ele, s_old.peek().min) < 0) //problem occurs here
{
s_old.push(new Element<T>(ele, ele));
}
else
{
s_old.push(new Element<T>(ele, s_old.peek().min));
}
}
}
T deque()
{
if (s_new.empty())
{
while (!s_old.empty())
{
s_new.push(s_old.pop());
}
}
return s_new.pop().element;
}
}
Now I will need to create a comparator for by T.
Lets say my T is an Integer:
class MyAwesomeIntegerComparator implements Comparator<Integer>{
#Override
public int compare(Integer first, Integer second)
{
return first - second;
}
}
Now using this:
public static void main(String args[])
{
MyQueue<Integer> q = new MyQueue<Integer>(new MyAwesomeIntegerComparator());
q.enqueue(1);
q.enqueue(2);
//System.out.println(q.s_old);
System.out.println(q.deque());
}
Summery
To sum up:
In java you can either compare by making the desired class compareable
Or by making it a separated Comperable just for it and then use it when needed.
Why would I ever need a Comperable ?
Lets say I have a class cow.
Sometimes I want to compare it by amount of milk it gives.
Sometime by wight.
I'l make a method that accepts any Cow comperator and it wont care what comparator its using.
For example, the Arrays.sort() method does exactly that.
sort(T[] a, Comparator<? super T> c)
How this helps.

Related

Efficient way to save last X amount of integers [duplicate]

A very simple & quick question on Java libraries: is there a ready-made class that implements a Queue with a fixed maximum size - i.e. it always allows addition of elements, but it will silently remove head elements to accomodate space for newly added elements.
Of course, it's trivial to implement it manually:
import java.util.LinkedList;
public class LimitedQueue<E> extends LinkedList<E> {
private int limit;
public LimitedQueue(int limit) {
this.limit = limit;
}
#Override
public boolean add(E o) {
super.add(o);
while (size() > limit) { super.remove(); }
return true;
}
}
As far as I see, there's no standard implementation in Java stdlibs, but may be there's one in Apache Commons or something like that?
Apache commons collections 4 has a CircularFifoQueue<> which is what you are looking for. Quoting the javadoc:
CircularFifoQueue is a first-in first-out queue with a fixed size that replaces its oldest element if full.
import java.util.Queue;
import org.apache.commons.collections4.queue.CircularFifoQueue;
Queue<Integer> fifo = new CircularFifoQueue<Integer>(2);
fifo.add(1);
fifo.add(2);
fifo.add(3);
System.out.println(fifo);
// Observe the result:
// [2, 3]
If you are using an older version of the Apache commons collections (3.x), you can use the CircularFifoBuffer which is basically the same thing without generics.
Update: updated answer following release of commons collections version 4 that supports generics.
Guava now has an EvictingQueue, a non-blocking queue which automatically evicts elements from the head of the queue when attempting to add new elements onto the queue and it is full.
import java.util.Queue;
import com.google.common.collect.EvictingQueue;
Queue<Integer> fifo = EvictingQueue.create(2);
fifo.add(1);
fifo.add(2);
fifo.add(3);
System.out.println(fifo);
// Observe the result:
// [2, 3]
I like #FractalizeR solution. But I would in addition keep and return the value from super.add(o)!
public class LimitedQueue<E> extends LinkedList<E> {
private int limit;
public LimitedQueue(int limit) {
this.limit = limit;
}
#Override
public boolean add(E o) {
boolean added = super.add(o);
while (added && size() > limit) {
super.remove();
}
return added;
}
}
Use composition not extends (yes I mean extends, as in a reference to the extends keyword in java and yes this is inheritance). Composition is superier because it completely shields your implementation, allowing you to change the implementation without impacting the users of your class.
I recommend trying something like this (I'm typing directly into this window, so buyer beware of syntax errors):
public LimitedSizeQueue implements Queue
{
private int maxSize;
private LinkedList storageArea;
public LimitedSizeQueue(final int maxSize)
{
this.maxSize = maxSize;
storageArea = new LinkedList();
}
public boolean offer(ElementType element)
{
if (storageArea.size() < maxSize)
{
storageArea.addFirst(element);
}
else
{
... remove last element;
storageArea.addFirst(element);
}
}
... the rest of this class
A better option (based on the answer by Asaf) might be to wrap the Apache Collections CircularFifoBuffer with a generic class. For example:
public LimitedSizeQueue<ElementType> implements Queue<ElementType>
{
private int maxSize;
private CircularFifoBuffer storageArea;
public LimitedSizeQueue(final int maxSize)
{
if (maxSize > 0)
{
this.maxSize = maxSize;
storateArea = new CircularFifoBuffer(maxSize);
}
else
{
throw new IllegalArgumentException("blah blah blah");
}
}
... implement the Queue interface using the CircularFifoBuffer class
}
The only thing I know that has limited space is the BlockingQueue interface (which is e.g. implemented by the ArrayBlockingQueue class) - but they do not remove the first element if filled, but instead block the put operation until space is free (removed by other thread).
To my knowledge your trivial implementation is the easiest way to get such an behaviour.
You can use a MinMaxPriorityQueue from Google Guava, from the javadoc:
A min-max priority queue can be configured with a maximum size. If so, each time the size of the queue exceeds that value, the queue automatically removes its greatest element according to its comparator (which might be the element that was just added). This is different from conventional bounded queues, which either block or reject new elements when full.
An LRUMap is another possibility, also from Apache Commons.
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/LRUMap.html
Ok I'll share this option. This is a pretty performant option - it uses an array internally - and reuses entries. It's thread safe - and you can retrieve the contents as a List.
static class FixedSizeCircularReference<T> {
T[] entries
FixedSizeCircularReference(int size) {
this.entries = new Object[size] as T[]
this.size = size
}
int cur = 0
int size
synchronized void add(T entry) {
entries[cur++] = entry
if (cur >= size) {
cur = 0
}
}
List<T> asList() {
int c = cur
int s = size
T[] e = entries.collect() as T[]
List<T> list = new ArrayList<>()
int oldest = (c == s - 1) ? 0 : c
for (int i = 0; i < e.length; i++) {
def entry = e[oldest + i < s ? oldest + i : oldest + i - s]
if (entry) list.add(entry)
}
return list
}
}
public class ArrayLimitedQueue<E> extends ArrayDeque<E> {
private int limit;
public ArrayLimitedQueue(int limit) {
super(limit + 1);
this.limit = limit;
}
#Override
public boolean add(E o) {
boolean added = super.add(o);
while (added && size() > limit) {
super.remove();
}
return added;
}
#Override
public void addLast(E e) {
super.addLast(e);
while (size() > limit) {
super.removeLast();
}
}
#Override
public boolean offerLast(E e) {
boolean added = super.offerLast(e);
while (added && size() > limit) {
super.pollLast();
}
return added;
}
}

Java look at elements in queue

So I'm making a search algorithm. I'm using a queue to store all of my objects
This is how I initialised it
Queue<Node> queue = new LinkedList<Node>();
I want to compare a variable in each object and order to queue. My plan is to use a for loop to compare the first object with each of the other objects and whichever object has the lowest variable is sent to the front of the queue. Then move onto the next object and repeat the process. My issue is I'm not sure how to retrieve an object from the queue that isn't the first object in the queue....
You could do a for loop through the Queue:
for (Node n : queue) {
do stuff with n
}
However, you aren't going to be able to remove items from the middle of the queue. Might I suggest a structure like an ArrayList?
In my opinion the best way is to use PriorityQueue. You can specify implementation of Comparator interface that will impose how elements should be sorted inside of queue.
Here is an example:
Let's say that this is your Node class:
public class Node {
// this field will be used to sort in queue
private int value;
public Node(int value) {
this.value = value;
}
public int getValue() {
return value;
}
#Override
public String toString() {
return "My value is: " + value;
}
}
And here is example of adding Nodes into queue:
import java.util.PriorityQueue;
import java.util.Random;
public class QueueExample {
public static void main(String[] args) {
Random r = new Random();
// Priority queue with custom comparator
PriorityQueue<Node> queue = new PriorityQueue<Node>(10, new SampleNodeComparator());
// adding 100 nodes with random value
for(int i = 0; i < 100; ++i) {
queue.add( new Node(r.nextInt(1000)));
}
// nodes will be removed from queue in order given by comparator
while(queue.size() != 0) {
System.out.println(queue.remove());
}
}
}
And the most important part - implementation of our custom comparator
import java.util.Comparator;
// our comparator needs to implements Comparator interface
public class SampleNodeComparator implements Comparator<Node> {
#Override
public int compare(Node o1, Node o2) {
/*
value that should be return from compare method should follow rules:
if o1 == o2 - return 0
if o1 > o2 - return any positive value
if o1 < 02 - return any negative value
*/
return o1.getValue() - o2.getValue();
}
}
When you run main method from QueueExample class you will see on console that values are removed from queue sorted by Node.value value.
Use Queue<E>#peek () to retrieve an object without removing it.
Some example code:
import java.util.*;
class Example {
public static void main (String[] args) throws Exception {
Queue<String> list = new PriorityQueue<>();
{ // Initialize the Queue
list.add ("Hello ");
list.add ("Mrs. ");
list.add ("DoubtFire! ");
}
System.out.println (list);
// Iterating through the Queue
String element;
while ( (element = list.peek()) != null) {
if (element.equals ("Mrs. ")) {
System.out.println ("\"Mrs\" found!");
}
System.out.println (element);
list.remove (element);
}
System.out.println (list); // Empty by now...
}
}
Output:
[DoubtFire! , Mrs. , Hello ]
DoubtFire!
Hello
"Mrs" found!
Mrs.
[]
Queue interface does not guarantee any particular order while iterating or polling so theoretically this task is impossible to implement with Queue.
Seeing your response to my comment, I think that in your case, you should use the PriorityQueue because it does what you need without needing you to reinvent the wheel, which is usually not recommended.
By default, the priority queue will use the default implementation of the compareTo method. Assuming that you have a composite type, you have two options:
You can make your custom class implement the Comparabale interface and have your sorting logic there.
Alternatively, you could pass your own comparator:
PriorityQueue<..> p = new PriorityQueue<..>(5, new Comparator<..>()
{
#override
public int compare(.. type1, .. type2)
{
//comparison logic done here.
}
}
You can take a look at this short tutorial for more information.

Iterating through elements of a data structure instead of Collection

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...

How to create Priority Queue that sorts based on certain attribute of class?

I have created a Node class:
public class Node {
int vertex;
double latency;
Node predecessor;}
public double getLatency()
{
return latency;
}
I want to create a Priority Queue that sorts the Nodes by latency from least to greatest. After research, I believe I need to override the Comparator?
PriorityQueue<Node> pqueue = new PriorityQueue<Node>(numVertices, new Comparator<Node>({
#Override
???
}
}
I'm not too sure how to override it.
You just actually need to compare both latencies. That means overriding the method compare of the class Comparator comparing the latency of both input Node:
PriorityQueue<Node> pqueue = new PriorityQueue<Node>(numVertices, new Comparator<Node>({
#Override
public int compare(Node a, Node b) {
return Integer.compare(a.getLatency(), b.getLatency());
}
}
However this only works for Java 7, for other versions:
new Integer(a.getLatency()).compareTo(new Integer(b.getLatency()));
If you don't want to create a new Object then compare both int as usual
The "???" in your example can be replaced with the following:
public int compare(Node a, Node b) {
if (a.getLatency() < b.getLatency())
return -1;
else if (a.getLatency() > b.getLatency())
return 1;
return 0;
}

Comparison operators in generic heap

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.

Categories

Resources