A SortedList.IndexOfKey(key) 返回项目的索引,其中 item.key >= key

发布于 2024-12-29 12:52:24 字数 333 浏览 1 评论 0 原文

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

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

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

(一般来说,我希望拥有类似Java的NavigableMap功能,即对排序的地图/字典进行高效迭代之类的功能,但现在,上述问题的答案就足够了,我可以用我的方式“扩展方法”从那里以某种方式)

SortedList<TKey, TValue>.IndexOfKey(key) returns -1 if key is not in the list.

Does this mean I have to implement a binary search myself if I want to find the index of the key in the list that is greater or equal to key? Or is there something out of the box that I overlooked?

I want to get the result in O(log(n)) of course, so please no LINQ iterate and filter magic.

(In general, I'd like to have something like Java's NavigableMap functionality, i.e. features like efficient iteration over a sorted map/dictionary, but for now, an answer to the above question would suffice, I can "extension-method" my way from there somehow)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

紫南 2025-01-05 12:52:24

所以,对于包括我自己在内的子孙后代,我再次需要 .net 中的 NavigableMap。适用于 SortedListBinarySearch 扩展方法以及适用于任何 IList 的重载。

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,至少可以派生出 IList 和数组。

SortedList 实际上可以派生自 IRandomAccess,以及 IRandomAccessIRandomAccess>

So here it is, for posterity, including myself, as I'm yet again in need of a NavigableMap in .net. BinarySearch extension methods that work for SortedList<TKey, TValue> and overloads that work for any 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;
    }
}

N.B. I wonder why there is no IRandomAccess<T> in .net, which at least IList<T> and arrays would derive from.

SortedList<TKey, TValue> could actually derive from IRandomAccess<TKey>, as well as IRandomAccess<TValue> and IRandomAccess<KeyValuePair<TKey, TValue>>.

叫嚣ゝ 2025-01-05 12:52:24

恐怕你不走运,没有任何内置的东西。

如果您为 IList 创建二分搜索扩展方法,则可以将其用于 Keys 属性。这有点烦人,但不太困难。

(框架的内置二进制搜索方法使用的约定 - Array List -- 是在没有找到该元素时返回下一个元素索引的按位补码。)

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

I'm afraid you're out of luck, there's nothing built-in.

If you create a binary search extension method for IList<T> then you could use it against the Keys property. This is a bit annoying, though not too difficult.

(The convention used by the framework's built-in binary search methods -- Array and List<T> -- is to return the bitwise complement of the index of the next element when the element isn't found.)

int index = yourSortedList.Keys.YourBinarySearchExtensionMethod(key);
if (index >= 0)
{
    // key found
}
else
{
    // key not found
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文