I need a sorted stack. I mean, the element removed from the stack must be the one with great priority. Stack dimension varies a lot (becomes bigger very fast).
I need also to search elements in that stack.
Does Java give some good implementation for this? What class or algorithm do you suggest for this?
I'm using a PriorityQueue right now which I consider reasonable except for searching, so I'm wondering if I can use something better.
I also need to remove elements!
In summary: I need to maintain a sorted stack/queue, get the element with greater priority fast and also remove elements as fast as possible
TreeSet is a sorted set. Set means no duplicates though.
add() adds an item, which is inserted in the correct sorted place.
pollLast() removes and returns the last item,
pollFirst() removes and returns the first item.
Java doesn't provide a PriorityStack, but you could easily write one by wrapping the PriorityQueue class and providing the push/pop methods to manage the underlying queue.
import java.util.Stack;
public class Q6_SortStack {
/**
* #param args
* Write a program to sort a stack in ascending order.
* You should not make any assumptions about how the stack is implemented.
* The following are the only functions that should be used to
* write this program: push | pop | peek | isEmpty.
*/
public static void main(String[] args) {
int[] array = {2,5,10,3,11,7,13,8,9,4,1,6};
Stack<Integer> s1 = new Stack<Integer>();
//int[] array = {2,4,1,6};
for(int i=0;i<array.length;i++){
s1.push(array[i]);
}
//displayStack(s1);
displayStack(sortStack(s1));
}
public static Stack<Integer> sortStack(Stack<Integer> s1){
Stack<Integer> s2 = new Stack<Integer>();
while(!s1.isEmpty()){
int temp = s1.pop();
while(!s2.isEmpty() && s2.peek()<temp){
s1.push(s2.pop());
}
s2.push(temp);
}
return s2;
}
public static void displayStack(Stack<Integer> s){
while(!s.isEmpty())
System.out.print(s.pop()+"->");
System.out.println("end");
}
}
You can always use two data structures. A priority queue and a map. The first will let you get the smallest/largest item, and the second will let you search items fast. You just need to wrap them in the logic to keep them in sink (which shouldn't be too hard)
You could modify/overload the method you use to push data into your stack such that it inserts into the correct or "sorted" position. Otherwise, if you're implementing the stack using an array of some primitive datatype, you could use Arrays.sort(*Stack data array goes here*) from the java.util package every time you push data into the stack.
Related
I want to implement Fibonacci Heap on Dijkstra Algorithm. I use this code for Fibonacci heap.
http://keithschwarz.com/interesting/code/?dir=fibonacci-heap
The problem is how to call the method: decreaseKey? It always give me the hint that (entry,double). But how to write an entry? The following is a simple example, how to fill the question mark?
FibonacciHeap<Integer> aa = new FibonacciHeap<>();
aa.enqueue(10, 1.01);
aa.enqueue(10, .2);
aa.enqueue(12, 3.2);
aa.enqueue(13, 3.4);
aa.decreaseKey(??????, newPriority);
decreaseKey() expects the first argument to be of type FibonacciHeap.Entry. 3 methods in the class return the Entrys of the heap:
public Entry<T> enqueue(T value, double priority);
public Entry<T> min();
public Entry<T> dequeueMin();
Each of the 3 methods return a different element, and modify the heap in their own way. Depending on your use case, you can store these Entrys in a variable and pass it to decreaseKey().
One such case would be storing the Entry while enqueuing it. Whenever you enqueue() something to the heap, it returns its corresponding Entry. From its documentation:
/**
* Inserts the specified element into the Fibonacci heap with the specified
* priority.
* ...
* #return An Entry representing that element in the tree.
*/
public Entry<T> enqueue(T value, double priority);
You can store it, and pass it to decreaseKey().
FibonacciHeap<Integer> aa = new FibonacciHeap<>();
FibonacciHeap.Entry entry = aa.enqueue(10, 1.01);
// ...
aa.decreaseKey(entry, newPriority);
I have an array which contains values pawnArray. I need to find the highest value in pawnArray so using a custom class method getPawn() I retrieve the highest value but I do
public static Pawn getPawn(Array<Pawn> strollpawns) {
Array<Pawn> pawns = strollpawns;
pawns.sort();
Pawn best = pawns.get(0);
return best;
}
I hence need to copy the array since this method doesn't work. How can I make a copy of this array?
If your problem is with Java arrays (the syntax is Pawn[]) then you have methods in class java.util.Arrays for many different operations on them. What you are asking for could be accomplished with:
Pawn[] newArr = Arrays.copyOf(oldArr, oldArr.length);
Or, since array classes implement Cloneable, also with:
Pawn[] newArr = (Pawn[]) oldArr.clone(); // I don't remember if the cast is necessary
Note that both of these provide shallow copies, that is, the arrays are independent of each other (you can sort one and the indexes in the other are unaffected) but their contents are not.
EDIT: it has been kindly pointed out to me that your Array<T> is actually a class in libgdx. Looking at the documentation, then, you could simply use the constructor taking another instance of Array to create your shallow copy, since the doc says that the new instance will have the same type of backing array (not the same instance). For example:
Array<T> newArr = new Array<>(oldArr); // oldArr can be either Array<? extends T> or T[]
I'm adding a separate answer to this, since you want to copy your array and sort it in order to retrieve the highest value. My other answer deals with copying the array, while tjago's answer deals with sorting with a custom Comparator in order to customize what the "max value" is. However, it seems that the libgdx Array<T> class has a method to do just what you want, without having to make a sorted copy of the array.
This solution saves you code, memory and time if you only need one value from the sorted array: the minimum, maximum, whatever. If you need more than one, it is likely that sorting the array will be faster.
The method I'm talking about is Array.selectRanked, which returns the nth element according to the provided Comparator. There is another method selectRankedIndex which returns the index of that element instead of the object itself. You could use it like this:
// If Pawn implements Comparable<Pawn>:
Pawn minVal = arr.selectRanked(Comparator.naturalOrder(), 1);
Pawn maxVal = arr.selectRanked(Comparator.naturalOrder(), arr.size);
// If it does not implement Comparable, you need to provide a Comparator<Pawn>:
// Assuming Pawn has an "int getValue()" method that we want to compare:
Pawn minVal = arr.selectRanked(Comparator.comparingInt(Pawn::getValue), 1);
// You could also write your own implementation directly:
Comparator<Pawn> comp = (a,b) -> /* your int-returning logic here */;
Pawn minVal = arr.selectRanked(comp, 1);
It seems you have a java related problem. To help you with sorting In java object programming there exist concept of method overriding and interfaces.
Special interface for sorting is Comparator, you can either put him inline in method like this.
Collections.sort(pawns ,new Comparator<Student>(){
public int compare(Pawn1 p1,Pawn2 p2){
// Write your logic here.
//ie.:
return p1.score - p2.score;
//or for different order
return p2.score - p1.score;
}});
if this comparator return value == 0 means the value are equal;
if value < 0 means p1 is bigger than p2, therefore swap them.
Or put him inside your Object class like:
Class Pawn implements Comparator {
private String name;
private Position[][] posXY;
private int value;
....
Pawn() { ... }
...
public int compare(Pawn1 p1,Pawn2 p2){
return p1.value- p2.value;
}
}
then in your code you can call as you originally intended:
pawns.sort();
Pawn best = pawns.get(0);
and as expected you should get an maximum value Pawn from ArrayList.
The above code is just sample and requires tunning. But You should get an good overview now that Java has no idea how to sort Objects defined by a programmer unless he implements the Comparator logic for Collection sorting.
for external reference I suggest running a simple example on tutorialpoint
Answer to your question: How can I create copy of a libgdx array
Array<Pawn> pawns = new Array<Pawn>(strollpawns);
or if the pawns Array object already exists
pawns.clear();
pawns.addAll(strollpawns);
The first solution will create a new Array object that will be deleted on completion of the function, meaning time lost by garbage collector!
But I agree with Tenfour04: Duplicating an array and sorting it is a very expensive way to select the biggest value.
I have float[] array of length 100. Is there a way I can select (pseudocode):
x = array[10:19];
To get elements 10,11,12,...,19 without copying over into another buffer? I'm in a mobile application where I don't want to waste space or time doing this. I'd rather just reference the pointers the system uses for array.
The most efficient way to do this would be to use System.arrayCopy(), which is much faster and more efficient than copying manually using a loop. It will require another array, but any approach you use (beyond just passing the original array around with a couple of ints representing the offset to use) will do this, and it's relatively cheap - the memory consuming bit is usually the objects that it's referencing rather than the array itself, and they are not copied.
No, there is no API to do that. The closest solution to this would be building your own class that wraps an existing array, and does the re-indexing:
class SubArray {
private final float[] data;
private final int offset;
private final int length;
public SubArray(float[] data, int offset, int length) {
this.data = data;
this.offset = offset;
this.length = length;
}
public float get(int index) {
if (index >= length) throw ...
return data[index + offset];
}
public void set(int index, float value) {
if (index >= length) throw ...
data[index + offset] = value;
}
}
If the result that you need is a new object that behaves like an array in all respects, including the indexing operator, you would need to make a copy.
(Update) Precondition: You should store the data in a Float[] instead of a float[], the performance-hit should be minimal.
You can use: Arrays.asList(array).subList(10, 20).
The Arrays.asList(array) does the following:
Returns a fixed-size list backed by the specified array. (Changes to the returned list "write through" to the array.) This method acts as bridge between array-based and collection-based APIs, in combination with Collection.toArray(). The returned list is serializable and implements RandomAccess.
Source
And then .subList(10, 20) returns you a List.
Then if you really want to work with arrays in the end, you could take the following lines:
List<Float> subList = Arrays.asList((Float[])array).subList(10, 20);
Float[] subArray = subList.toArray(new Float[subList.size()]);
(Update) Changed Arrays.asList(array) to Arrays.asList((Float[])array) such that it is correct now.
From documentation:
Returns an array containing all of the elements in this list in proper sequence (from first to last element); the runtime type of the returned array is that of the specified array. If the list fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this list.
If the list fits in the specified array with room to spare (i.e., the array has more elements than the list), the element in the array immediately following the end of the list is set to null. (This is useful in determining the length of the list only if the caller knows that the list does not contain any null elements.)
Like the toArray() method, this method acts as bridge between array-based and collection-based APIs. Further, this method allows precise control over the runtime type of the output array, and may, under certain circumstances, be used to save allocation costs.
Suppose x is a list known to contain only strings. The following code can be used to dump the list into a newly allocated array of String:
Source
This should ensure that no data is wasted, the only thing to be careful about could be autoboxing.
UPDATE: Changed my answer such that it now is correct under a precondition.
What is the problem of using a simple for loop? Objects are in java called by reference.
So, executing copying the array does not copy the objects.
float[] subarray = new float[10];
for(int i = 10, j = 0; i < 19; i++, j++) {
subarray[j] = x[i];
}
The array[0] is a reference to the object of x[0].
edit: This only applies for objects, and i don't know if it also applies to a float
Suppose I read a stream of integers. The same integer may appear more than once in the stream. Now I would like to keep a cache of N integers that appeared most frequently. The cache is sorted by the frequency of the stream elements.
How would you implement it in Java?
You want to use a binary indexed tree, the code in the link is for C++ and should be fairly straightforward to convert into Java (AFAICT the code would be the same):
Paper Peter Fenwick
Implementation in C++
Use a Guava Multiset and sort it by frequency
public class MyData implements Comparable<MyData>{
public int frequency = 0;
public Integer data;
#Override
public int compareTo(MyData that) {
return this.frequency - that.frequency;
}
}
Have it stored in a PriorityQueue
Create an object model for the int, inside create a Count property. Create a SortedVector collection extending the Vector collection. Each time an integer occurs, add it to the vector if it doesn't exist. Else, find it, update the count property += 1, then call Collections.sort(this) within your Vector.
Do you know the range of the numbers? If so, it might make sense to use an array. For example, if I knew that the range of the numbers was between 0 and 10, I would make an array of size 10. Each element in this array would count the number of times I've seen a given number. Then, you just have to remember the most frequently seen number.
e.g.
array[10];
freq_index = -1;
freq_count = -1;
readVal(int n){
array[n]+=1;
if array[n] > freq_count
freq_index = n;
freq_count = array[n];
}
Of course, this approach is bad if the distribution of numbers is sparse.
I'd try a priority queue.
I have two collections - an ArrayList and a Stack. I use the stack because I needed some simple pop/push functionality for this bit of code. The ArrayList is essentially the out variable as this is a small section of code in the function.
So, the variables are defined as such, then code is run to add elements to the stack.
ArrayList<String> out = new ArrayList<String>();
/* other code.. */
Stack<String> lineStack = new Stack<String>();
/* code that adds stuff to the stack */
The question is, now that I have a fully populated stack, how do I place it in the out ArrayList in a reverse order then from the pop order.
My first thought up solution was
while(!lineStack.empty()) {
out.add(0, lineStack.pop());
}
... which works, but I worry about the efficiency of adding an element to the beginning of the ArrayList (which forces all existing elements to need to shift.. it's a linked list (I believe).. big deal.. but still a concern). Also, I am running this through a loop... perhaps unnecessarily.
So, my second solution that didn't involve looping (at least in my code, i'm sure the back end calls are doing it).
List l = lineStack.subList(0, lineStack.size());
out.addAll(l);
I know I don't need to allocate the list, but it'll keep for cleaner code. However, I am not sure if this will give me a particularly helpful performance gain.
So, my question is: Which of these will likely be most efficient for SMALL to MEDIUM size sets? If there is a more efficient solution, what would it be?
The Iterable<T> implementation order of Stack<T> goes in the order you want anyway, so you can just use
new ArrayList<String>(stack);
Here's a short but complete example:
import java.util.*;
public class Test
{
public static void main(String[] args)
{
Stack<String> stack = new Stack<String>();
stack.push("Bottom");
stack.push("Middle");
stack.push("Top");
List<String> list = new ArrayList<String>(stack);
for (String x : list)
{
System.out.println(x);
}
}
}
This prints out:
Bottom
Middle
Top
(which is the opposite order to what you'd get if you popped them).
EDIT: One other question - do you really need it in an ArrayList<String> anyway? Stack<T> implements List<T>; what special features of ArrayList do you need? (I'm not saying you don't need them, just checking!)
Stack is subclass of Collections and Collections has reverse method, So you can just do -
Stack originalStack = ...
Collections.reverse(originalStack);
If you don't need it as an array, but another stack would work, why not:
Stack<String> reversedStack = new Stack<String>();
while (!oldStack.empty())
{
reversedStack.push(oldStack.pop());
}
Quick, simple, and easy to see what it's doing.
Subclass the ArrayList and add a pop and push method.
Use this as the Stack class.
When you are ready, assign it to an Arraylist variable and you're ready
making use of Stack.toArray is simple:
#Test
public void stackToList() {
Stack<String> stack = new Stack<String>();
stack.push("aaa");
stack.push("bbb");
stack.push("ccc");
List<String> list= Arrays.asList(stack.toArray(new String[0]));
Assert.assertEquals(Arrays.asList("aaa", "bbb", "ccc"), list);
}