【问题标题】:C# ordered dictionary object that supports finding closest key?支持查找最近键的 C# 有序字典对象?
【发布时间】:2016-02-20 15:24:27
【问题描述】:

在 C# 中是否有任何可用的有序字典集合提供了一种现成的方法来查找大于某个值的第一个键(如果所查找的值不存在)?

if (!Dictionary.ContainsKey(some_key)) 然后根据字典的排序谓词返回下一个key > some_key

如果有一种巧妙的方式与代表一起做这件事,我们同样会感激不尽!

【问题讨论】:

  • 试试SortedDictionarySortedDictionary<string, string> openWith = new SortedDictionary<string, string>()
  • 我认为它没有实现。正如@Vadim 所说,.Net 中有 SortedDictionary,您可以尝试一下。使用 Linq,我们有 OrderBy() 方法,它允许我们对数据进行排序,但只是排序。
  • 您最好的选择可能是使用SortedList<TKey, TValue> 并对键进行二分搜索。 SortedList 有一个 IndexOfKey 方法,但它不允许您在搜索失败的情况下找到密钥的位置。不幸的是,IList<Key> 也没有内置的二进制搜索方法,因此您必须手动执行此操作。
  • 我的意思是可以从 SortedDictionary 键或值创建一个列表,并使用它们的顺序迭代槽。

标签: c# .net dictionary data-structures ordereddictionary


【解决方案1】:

Here is a great binary-search implementation for any sorted IList:如果不存在确切的键,则返回下一个最大键的~index

在范围内使用该类,可以执行以下操作:

SortedList myList;
int nextBiggestKey; // Index of key >= soughtValue
if((nextBiggestKey = myList.Keys.BinarySearch(soughtValue)) < 0)
{
   if(~nextBiggestKey > myList.Count) continue; // soughtValue is larger than largest key in myList
   nextBiggestKey = ~nextBiggestKey
}

【讨论】:

    【解决方案2】:

    正如 Vadim 所建议的,您最好的选择是 SortedDictionary 实现,它存储已排序的键。从那里您可以执行以下操作:

    var next = dictionary.ContainsKey(key)
                    ? dictionary[key]
                    : dictionary.FirstOrDefault(kvp => kvp.Key > key).Value;
    

    dictionary.FirstOrDefault 将返回第一个键值对,其中键大于所需键。如果没有,则返回一个空白键值对 {,} 并且返回的值应该是存储类型的默认值。因为我在玩 SortedDictionary,所以它返回 null。

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                var dictionary = new SortedDictionary<int, string> {{1, "First"}, {2, "Second"}, {10, "10th"}};
                Console.WriteLine(GetNext(1, dictionary));
                Console.WriteLine(GetNext(3, dictionary));
                Console.WriteLine(GetNext(11, dictionary));
    
                Console.ReadLine();
            }
    
            private static string GetNext(int key, SortedDictionary<int, string> dictionary)
            {
                return dictionary.ContainsKey(key)
                    ? dictionary[key]
                    : dictionary.FirstOrDefault(kvp => kvp.Key > key).Value;
            }
        }
    }
    

    【讨论】:

    • O(lg N) 应该可能时,这会通过键进行线性搜索。
    • 如果性能是一个问题,它肯定可以改进,特别是 b/c 键是排序的。这只是为了展示它是如何完成的。
    猜你喜欢
    • 2010-12-14
    • 2012-09-06
    • 2012-12-19
    • 2015-05-16
    • 1970-01-01
    • 2023-01-05
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多