I am looking for the fastest way to decide whether or not a point on a line is within a subset of this line. I am given an integer Point, and I also have a "list" of either:
In this example, if the value of my point is 5, then I return true because it is included in an interval, same for 55. If my point is equal to 1000, I also return true because it matches the list of points.
I am looking for a fast way (quicker than linear) to check for this condition, WITHOUT having to instanciate as many integer as there are possible points (ie, for a 1:1000 interval I don't want to instanciate 1000 integers). Can this be done in a logarithmic time?
Thanks
edit : you can consider that any time taken to pre-process the list of data is equal to 0, because once my initial intervals are processed I need to apply this test to 10k points
1) Sort all intervals in increasing order of start time. This step takes O(nLogn) time. 2) In the sorted array, if start time of an interval is less than end of previous interval, then there is an overlap.
Traverse all the set of intervals and check whether the consecutive intervals overlaps or not. If the intervals(say interval a & interval b) doesn't overlap then the set of pairs form by [a. end, b. start] is the non-overlapping interval.
The basic idea is 1) first take input_start to test_start (if both of them are not equal and input_start is min) 2) always take test_start and test_end 3) take test_end to input_end if test_end is less than input end (and end_input and end_test are not equal).
Hm, maybe you can use an interval or a segment tree:
If you have the integers ranges sorted and the ranges are non-overlapping, you can perform binary search to find the correct range in logarithmic time.
Are there any constraint on the range? Based on that you can probably come up with hashing function to search in constant time. But this depends on how your constraints are.
After reflexion, I think that the following code should work in logarithmic time, excluding the time needed to build the map:
enum pointType {
point,
open,
close
};
std::map<long int, pointType> mapPoints;
mapPoints.insert(std::pair<long int, pointType>(3, point));
//create the 5:10 interval:
mapPoints.insert(std::pair<long int, pointType>(5, open));
mapPoints.insert(std::pair<long int, pointType>(10, close));
int number = 4;
bool inside = false;
std::map<long int, pointType>::iterator it1 = mapPoints.lower_bound(number);
if(it1->first == number || it1->second == close) {
inside = true;
}
I think this should work as long as the map is filled properly with non-overlapping intervals
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