【问题标题】:Dictionary-like structure with custom search behavior具有自定义搜索行为的类字典结构
【发布时间】:2013-01-23 05:49:33
【问题描述】:

我正在寻找一种可以搜索特定键的数据结构。关键是间隔。一旦将单个值传递给此结构,它应该找到正确的间隔(适当的键),然后该键可能指向其他几个值。

我搜索了多个值的一些键,发现如下:

Dictionary<double,LinkedList<T>>

但是这里的键值是一个简单的double,不是区间类型。如果是区间类型,我必须将区间作为键传递。但是我需要基于单个值进行搜索并找到区间。

换句话说,我们能否拥有一个具有自定义搜索行为的类字典结构?(例如将搜索作为 Func 参数传递。)

【问题讨论】:

  • 使用“类字典结构”,我的意思是将键映射到值,但我们不会将确切的键传递给它来查找值。相反,我们传递一些东西然后映射发生并且......
  • 你可以试试 Dictionary,LinkedList>
  • @RTROkzzz 区间可能是连续的而不是离散的
  • :我认为您需要自己的逻辑来首先从给定的间隔中找到键,然后该键可能对进一步的逻辑有用。
  • @RTROkzzz 也许你是对的。但我想知道是否有人有更好的想法。

标签: c# dictionary customization


【解决方案1】:

我不知道这样的现有结构。但是有很多方法可以自己解决这个问题。首先想到的是为字典写一个扩展方法,像这样:

public static class DictionaryRangeExtensions
{
    public IEnumerable<T> FindValuesInRange(this Dictionary<double,T> dictionary, double lowerBound, double upperBound)
    {
         dictionary.Where(kvp=> kvp.Key > lowerBound && kvp.Key < uppoerBound).Select(kvp=>kvp.Value);
    }
}

【讨论】:

  • 好主意。但是这里的 this 关键字是什么意思? “这本词典……”
  • 我不想找到一个范围内的每个键。我的键是一些范围,我有一个值。所以我需要根据该值找到正确的键(范围)。 (范围不重叠)
  • 扩展方法就是这样工作的。这意味着您可以像这样使用它:var values = myDictionary.FindValuesInRange(2.3, 5.7);
  • +0,虽然正确,但答案显示线性搜索与您从字典中按键查找获得的性能相差无几...
  • 我发布了另一个答案,因为我完全误解了这个问题。
【解决方案2】:

如果希望将范围作为键并按值查找,我认为这将作为键:

public class Range
{
   public Range(double lower, double upper)
   {
       this.lower = lower;
       this.upper = upper;
   }

   public override Equals(object obj)
   {
       if(obj is double) return ((double)obj) > lower && ((double)obj) < upper;
       //sensibly complete this method
   }

   //also override GetHashcode, probably to use the hashcode of upper and lower
}

【讨论】:

  • +1:当值可以映射到常数时间间隔(即 1.5 -> [0,2])时,适用于搜索范围和按值
【解决方案3】:

对于非重叠间隔,如果您可以将值映射到以恒定时间搜索的间隔 - @tallseth 建议在普通字典中将间隔作为键。

如果您必须搜索该值所属的区间 - 将区间存储为排序数组(您可以轻松地这样做,因为区间不重叠,因此为每对区间定义了 &lt;)。比你二分查找找到区间值落入。使用间隔,您可以索引字典或让数据包含“间隔”,并使用适当的函数从 dat 中选择间隔进行排序/散列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多