【问题标题】:A SortedList.IndexOfKey(key) that returns the index of the item where item.key >= key一个 SortedList.IndexOfKey(key),它返回 item.key >= key 的项目的索引
【发布时间】:2012-02-20 06:17:42
【问题描述】:

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

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

我当然想得到 O(log(n)) 的结果,所以请不要使用 LINQ 迭代和过滤魔法。

(一般来说,我希望有类似 Java 的 NavigableMap 功能,即在排序的地图/字典上进行高效迭代等功能,但现在,对上述问题的回答就足够了,我可以“扩展方法“我从那里不知何故)

【问题讨论】:

  • 很奇怪List有二分查找,而SortedList没有二分查找。

标签: .net sortedlist


【解决方案1】:

恐怕你运气不好,没有内置任何东西。

如果您为IList<T> 创建二进制搜索扩展方法,那么您可以针对Keys 属性使用它。这有点烦人,虽然不是太难。

(框架内置的二分查找方法——Array 和List<T>——使用的约定是在未找到元素时返回下一个元素的索引的按位补码。)

int index = yourSortedList.Keys.YourBinarySearchExtensionMethod(key);
if (index >= 0)
{
    // key found
}
else
{
    // key not found
}

【讨论】:

  • 感谢您指出内置 List.BinarySearch 方法。有了这个,剩下的就是一点管道。 (并不是说实现二分搜索需要博士学位)
【解决方案2】:

因此,为了后代,包括我自己,因为我再次需要 .net 中的NavigableMap。 BinarySearch 适用于 SortedList<TKey, TValue> 的扩展方法和适用于任何 IList<T> 的重载。

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;
    }
}

注意我想知道为什么 .net 中没有 IRandomAccess&lt;T&gt;,至少 IList&lt;T&gt; 和数组会从中派生出来。

SortedList&lt;TKey, TValue&gt; 实际上可以派生自 IRandomAccess&lt;TKey&gt;,以及 IRandomAccess&lt;TValue&gt; 和 IRandomAccess&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 2019-04-26
    • 2011-09-12
    • 2020-12-23
    • 1970-01-01
    • 2022-09-29
    相关资源
    最近更新 更多