SortedList< TKey,TValue> .IndexOfKey(key)如果 key 不在列表中,则返回-1。
这是否意味着如果我想在列表中找到大于或等于 key 的键的索引,我必须自己实现二进制搜索?或者是否有一些我忽略的开箱即用的东西?
我想在O(log(n))中得到结果,所以请不要LINQ迭代并过滤魔法。
(一般来说,我希望有类似Java的NavigableMap功能,即在排序的地图/字典上有效迭代等功能,但就目前而言,上述问题的答案就足够了,我可以“扩展方法“不知怎的,我从那里开始”
答案 0 :(得分:2)
我担心你运气不好,内心没什么。
如果为IList<T>
创建二进制搜索扩展方法,则可以将其用于Keys
属性。这有点烦人,但并不太难。
(框架的内置二进制搜索方法使用的约定 - Array
和List<T>
- 是在元素不是时返回下一个元素的索引的按位补码找到。)
int index = yourSortedList.Keys.YourBinarySearchExtensionMethod(key);
if (index >= 0)
{
// key found
}
else
{
// key not found
}
答案 1 :(得分:2)
所以在这里,对于后人,包括我自己,因为我还需要一个NavigableMap
.net。适用于BinarySearch
的{{1}}扩展方法以及适用于任何SortedList<TKey, TValue>
的重载。
IList<T>
N.B。我想知道为什么.net中没有public static class BinarySearch4All
{
public static int BinarySearch<TKey, TValue>(this SortedList<TKey, TValue> sortedList,
TKey value, IComparer<TKey> comparer = null)
{
return BinarySearch(sortedList, 0, sortedList.Count, value, comparer);
}
public static int BinarySearch<TKey, TValue>(this SortedList<TKey, TValue> sortedList,
int index, int length, TKey value, IComparer<TKey> comparer = null)
{
return BinarySearch(sortedList.Keys, index, length, value, comparer);
}
public static int BinarySearch<T>(this IList<T> list, T value, IComparer<T> comparer = null)
{
return BinarySearch(list, 0, list.Count, value, comparer);
}
// algorithm courtesy of http://referencesource.microsoft.com/#mscorlib/system/collections/generic/arraysorthelper.cs#114ea99d8baee1be
public static int BinarySearch<T>(this IList<T> list, int index, int length,
T value, IComparer<T> comparer = null)
{
if (comparer == null)
comparer = Comparer<T>.Default;
int lo = index;
int hi = index + length - 1;
while (lo <= hi)
{
int i = lo + ((hi - lo) >> 1);
int order = comparer.Compare(list[i], value);
if (order == 0) return i;
if (order < 0)
lo = i + 1;
else
hi = i - 1;
}
return ~lo;
}
}
,至少IRandomAccess<T>
和数组会派生出来。
IList<T>
实际上可以来自SortedList<TKey, TValue>
,以及IRandomAccess<TKey>
和IRandomAccess<TValue>
。