一个SortedList.IndexOfKey(key),它返回item.key> = key的项的索引

时间:2012-01-27 07:36:55

标签: .net sortedlist

SortedList< TKey,TValue> .IndexOfKey(key)如果 key 不在列表中,则返回-1。

这是否意味着如果我想在列表中找到大于或等于 key 的键的索引,我必须自己实现二进制搜索?或者是否有一些我忽略的开箱即用的东西?

我想在O(log(n))中得到结果,所以请不要LINQ迭代并过滤魔法。

(一般来说,我希望有类似Java的NavigableMap功能,即在排序的地图/字典上有效迭代等功能,但就目前而言,上述问题的答案就足够了,我可以“扩展方法“不知怎的,我从那里开始”

2 个答案:

答案 0 :(得分:2)

我担心你运气不好,内心没什么。

如果为IList<T>创建二进制搜索扩展方法,则可以将其用于Keys属性。这有点烦人,但并不太难。

(框架的内置二进制搜索方法使用的约定 - ArrayList<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>