【问题标题】:Suggest data structure suitable for key range lookup建议适合键范围查找的数据结构
【发布时间】:2017-01-02 09:05:03
【问题描述】:

我正在寻找类似于 SCG.Dictionary 但将数字范围作为键的数据结构。

对性能要求最高的主要操作是查找与指定范围重叠的键。

例如,假设如下图

[ 5, 15] -> King
[35, 50] -> Bear
[25, 40] -> Doll

当 [10, 30] 被传递给搜索算法时,它必须回复以下条目:

[ 5, 15] -> King
[25, 40] -> Doll

理想的搜索方法应该返回 IEnumerable 而不是将结果复制到中间容器中。类似于SortedSet.GetViewBetween

使用模式类似于

var lookup = new RangeDictionary<int>();
lookup.Add( 5, 15, 'King' );
lookup.Add( 35, 50, 'Bear' );
lookup.Add( 25, 40, 'Doll' );

var results = lookup.FindIntersection( 10, 30 );
foreach( var pair in results )
  Console.WriteLine( "[{0}, {1}] -> {2}", pair.Key.From, pair.Key.To, pair.Value );

有现成的解决方案吗?

【问题讨论】:

  • 你的例子正确吗? [10,35] 的结果是什么?应该是King, Bear 还是King, Doll 还是King, Bear, Doll
  • 自己编写似乎很容易,您为什么要为此寻找现成的解决方案?
  • 我认为你在寻找区间树,见stackoverflow.com/questions/303591/…

标签: c#


【解决方案1】:

这是一种可能的实现方式:

public class RangeDictionary<T> : Dictionary<Range, T>
{
    public void Add(int from, int to, T value)
    {
        Add(new Range(from, to), value);
    }

    public IEnumerable<KeyValuePair<Range, T>> FindIntersection(int from, int to)
    {
        return this.Where(x => x.Key.IntersectWith(from, to));
    }
}

public struct Range
{
    public Range(int from, int to)
        : this()
    {
        From = from;
        To = to;
    }
    public int From { get; }
    public int To { get; }

    public bool IntersectWith(int from, int to)
    {
        return this.From <= to && this.To >= from;
    }
}

您可以在 this link 上查看一个实时示例。

【讨论】:

  • 建议的结构意味着在我追求比 O(n) 更快的东西时进行全面扫描
  • 不仅是 O(n),从基集合类派生是一种非常糟糕的做法
  • @George 我没有看到任何其他建议...为什么您认为从集合派生如此糟糕,因为 .net 框架已经包含从字典派生的类。 .
  • @ZohadPeled 因为在你的实现中没有什么是你不能用扩展方法做的。 stackoverflow.com/questions/3748931/… 在答案中几乎没有其他好的论据可供您考虑。
  • 我什至不需要一个方法,它只是包装了一个 linq...但是它提供了更好的可读性,所有的类也一样...
猜你喜欢
  • 1970-01-01
  • 2011-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
  • 1970-01-01
  • 1970-01-01
  • 2013-09-27
相关资源
最近更新 更多