适当的数据结构,用于快速搜索“两对”之间的长度

时间:2013-04-26 10:51:42

标签: c#

我目前(概念上)有:

IEnumerable<Tuple<long, long, Guid>>

给定long,我需要找到“对应的”GUID

long s对不应该重叠,尽管对之间可能存在间隙,例如:

1, 10, 366586BD-3980-4BD6-AFEB-45C19E8FC989
11, 15, 920EA34B-246B-41B0-92AF-D03E0AAA2692
20, 30, 07F9ED50-4FC7-431F-A9E6-783B87B78D0C

对于每个输入long,应该有01匹配GUID s。

因此7的输入应返回366586BD-3980-4BD6-AFEB-45C19E8FC989

16的输入应返回null

更新:我有大约90K对

如何将此内存存储在内存中以便快速搜索?

由于

3 个答案:

答案 0 :(得分:6)

只要它们按顺序存储,你就可以根据“范围的开始”和候选者进行二进制搜索。一旦找到具有最大“范围开始”的条目,该条目小于或等于您的目标数字,那么您已经找到了具有正确GUID的条目,或者您已经证明您已经命中了差距(因为范围开始较小的条目的范围 end 的范围低于目标)。

您可以通过使其成为Dictionary<long, Guid?>来简单地简化逻辑,并且只记录起点,为每个间隙添加一个空值的条目。然后,您只需要找到最高键小于或等于目标数的条目,然后返回该值。

答案 1 :(得分:2)

试试这个(对不起,不是IEnumerable的解决方案):

public static Guid? Search(List<Tuple<long, long, Guid>> list, long input)
{
    Tuple<long, long, Guid> item = new Tuple<long,long,Guid> { Item1 = input };
    int index = list.BinarySearch(item, Comparer.Instance);
    if (index >= 0) // Exact match found.
        return list[index].Item3;
    index = ~index;
    if (index == 0) 
        return null;
    item = list[index - 1];
    if ((input >= item.Item1) && (input <= item.Item2))
        return item.Item3;
    return null;
}

public class Comparer : IComparer<Tuple<long, long, Guid>>
{
    static public readonly Comparer Instance = new Comparer();

    private Comparer()
    {
    }

    public int  Compare(Tuple<long,long,Guid> x, Tuple<long,long,Guid> y)
    {
        return x.Item1.CompareTo(y.Item1);
    }
}

答案 2 :(得分:1)

B树实际上相当不错。具体来说,一个B + -tree,其中每个分支指针都以您的范围的开头为关键字。叶数据可以包含上限,因此您可以正确处理间隙。我不确定它是否是你能在任何地方找到的最好的,你需要自己设计它,但它当然应该有非常好的性能。