Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Lower Bound function on a SortedList<K ,V>?

Is there a Lower Bound function on a SortedList<K ,V>? The function should return the first element equal to or greater than the specified key. Is there some other class that supports this?

Guys - please read the question once again. I do not need a function that returns the key if it is present. I'm interested in scenario when there is no exact key matching.

I'm interested in O(log n) time. It means that I do not have a problem with foreach loop, but rather would like to have an efficient way of doing this.

I have done some tests on this.

Linq statements are not optimized by neither the compiler nor runtime machine, so they walk through all collection elements and are slow O(n). Based on Mehrdad Afshari answer, here is a Binary Search that works in O(log n) on the Keys collection:

public static int FindFirstIndexGreaterThanOrEqualTo<T>(             this IList<T> sortedCollection, T key         ) where T : IComparable<T> {     int begin = 0;     int end = sortedCollection.Count;     while (end > begin) {         int index = (begin + end) / 2;         T el = sortedCollection[index];         if (el.CompareTo(key) >= 0)             end = index;         else             begin = index + 1;     }     return end; } 
like image 248
agsamek Avatar asked Feb 27 '09 12:02

agsamek


People also ask

What is the function of lower bound?

The lower_bound() method in C++ is used to return an iterator pointing to the first element in the range [first, last) which has a value not less than val. This means that the function returns an iterator pointing to the next smallest number just greater than or equal to that number.

What is lower bound of binary search?

With them, we can find position of the smallest element in the list bigger than or equal to the target (lower bound), or the smallest element bigger than the target (upper bound).

What is upper bound and lower bound in STL?

In a Vector, lower bound returns an iterator pointing to the first element in the range that does not compare the given value. Upper Bound returns an iterator pointing element in the range that smaller than given value.


2 Answers

Binary search the SortedList.Keys collection.

Here we go. This is O(log n):

private static int BinarySearch<T>(IList<T> list, T value) {     if (list == null)         throw new ArgumentNullException("list");     var comp = Comparer<T>.Default;     int lo = 0, hi = list.Count - 1;     while (lo < hi) {             int m = (hi + lo) / 2;  // this might overflow; be careful.             if (comp.Compare(list[m], value) < 0) lo = m + 1;             else hi = m - 1;     }     if (comp.Compare(list[lo], value) < 0) lo++;     return lo; }  public static int FindFirstIndexGreaterThanOrEqualTo<T,U>                           (this SortedList<T,U> sortedList, T key) {     return BinarySearch(sortedList.Keys, key); } 
like image 94
mmx Avatar answered Sep 19 '22 21:09

mmx


I'd go with LINQ (presuming you're using C#3), but using the overload of FirstOrDefault that takes a predicate:

first = sortedList.FirstOrDefault(x => x >= theObjectForComparison); 

(a lot of the other Enumerable methods can also take predicates which is a nice shortcut)

like image 25
Dave W Avatar answered Sep 21 '22 21:09

Dave W