Suppose, I have an unsorted array of ranges. For e.g
class CreditRange{
long credits;
int id;
}
Now I want to find, given credit count value belongs to which one of the CreditRange.
Possible Set<CreditRange>
of values can be
CreditRange :{id:1,credits:0}
CreditRange :{id:2,credits:100}
CreditRange :{id:3,credits:500}
CreditRange :{id:4,credits:250}
Case 1 : Now when user enters Credits = 50, this range comparator should give answer as
CreditRange :{id:1,credits:0}
Case 2 : Now when user enters Credits = 300, this range comparator should give answer as
CreditRange :{id:4,credits:250}
Case 3 : Now when user enters Credits = 600, this range comparator should give answer as
CreditRange :{id:3,credits:500}
We can assume the ranges array takes ~1M and fits the memory. I am looking for an easy algorithm, which uses only standard JDK collections without any 3d-party libraries and special data structures, but works reasonably fast.
What would you suggest?
between() is a static method of the Range which is used to obtain an instance of Range with the specified minimum and maximum value. The specified minimum and maximum values are inclusive in nature.
A range can be further defined as either open or closed based whether the range is exclusive or inclusive of the endpoints. open(a, b) : It represents a < range < b, and in notation form, (a, b). closed(a, b) : It represents a <= range <= b, and in notation form, [a, b].
ValueRange. of(minValue, maxValue); range. isValidIntValue(x); it returns true if minValue <= x <= MaxValue - i.e. within the range.
In Java, the Range method is available in IntStream as well as LongStream class. In IntStream class, it helps in returning sequentially ordered values of IntStream in the range mentioned as parameters of the function.
I guess, it's not the range you are talking about. Rather you want the largest element that is less than your passed element.
You can follow the below steps to solve the problem:
Comparator
for your class, which compares on the basis of credits
TreeSet
, passing an instance of that comparator to it's constructor. It will sort the item inside it, as per the comparator.TreeSet#floor(E)
method to get the greatest element which is less than E
, as per the comparator. Of course, you have to create an object of CreditRange
to search. You can't just search for 300
.Demo code:
NavigableSet<Integer> set = new TreeSet<>();
set.add(0); set.add(100);
set.add(250); set.add(500);
System.out.println(set.floor(50)); // 0
System.out.println(set.floor(300)); // 250
And please rename your class. It is not depicting the range in any manner. It should perhaps be better named as CreditBound
as specified by Jon Skeet in comments.
As mentioned by Rohit, one easy method is to use TreeSet floor (another is to implement a a modified variant of Binary search. this is a more complete answer:
package test;
import java.util.TreeSet;
class CreditRange implements Comparable<CreditRange> {
long credits;
int id;
public CreditRange(int id, long credits) {
this.id = id;
this.credits = credits;
}
public CreditRange(long credits) {
this.id = -1;
this.credits = credits;
}
@Override
public int compareTo(CreditRange o) {
return credits < o.credits ? -1 : credits > o.credits ? 1 : 0;
}
@Override
public String toString() {
return "id:" + id + ", credits:" + credits;
}
}
public class Test {
public static void main(String[] args) {
TreeSet<CreditRange> set = new TreeSet<>();
set.add(new CreditRange(1, 0));
set.add(new CreditRange(2, 100));
set.add(new CreditRange(3, 500));
set.add(new CreditRange(4, 250));
System.out.println(set.floor(new CreditRange(50)));
System.out.println(set.floor(new CreditRange(300)));
System.out.println(set.floor(new CreditRange(600)));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With