C# 如何有效地搜索带有不等式的排序集?

C# 如何有效地搜索带有不等式的排序集?,c#,.net-4.0,sortedset,C#,.net 4.0,Sortedset,好的,假设我有一个int类型的强类型SortedSet。我想找到集合中小于x的最大数 也许这是错误的数据结构,但我的直觉是我有一个分类的集合。当然,我应该能够通过.NET framework进行这种类型的搜索是有意义的?除非我遗漏了什么,否则请使用Linq的LastOrDefault扩展方法: var lastBefore = set.LastOrDefault(num => num < x); // x is your search number if (lastBefore &l

好的,假设我有一个int类型的强类型SortedSet。我想找到集合中小于x的最大数


也许这是错误的数据结构,但我的直觉是我有一个分类的集合。当然,我应该能够通过.NET framework进行这种类型的搜索是有意义的?

除非我遗漏了什么,否则请使用Linq的
LastOrDefault
扩展方法:

var lastBefore = set.LastOrDefault(num => num < x); // x is your search number
if (lastBefore < set.ElementAt(0))
{
    // Nothing in the set is smaller
}
else
{
    // lastBefore is the last number smaller then search number
}
var lastBefore=set.LastOrDefault(num=>num
由于
分类数据集
不提供按索引的直接访问,因此您必须依赖枚举(线性搜索-O(n))。一种可能更好的方法是使用and
Last
,但看起来您无法在不枚举视图中所有元素的情况下获取最后一个元素

通过索引直接访问的集合(即,
列表
)将允许您使用O(lg n)性能进行二进制搜索-因此,如果您需要搜索大量数据,则使用
ToList
可以在使用时提供更好的整体性能(这将为您提供查找的下一个元素的位置)

//开始二进制搜索方法的示例
//不处理项目不在列表中的情况(x=1)。
//必须对列表进行排序,这种情况从排序集开始:sortedSet.ToList()
var list=新列表{1,3,5,7,8,9};
var index=list.BinarySearch(8);
Console.WriteLine(索引<0?list[~index-1]:list[index-1]);

请注意,即使对集合进行了排序,这也是O(n),通常人们也会期望O(lg n)的性能,但据我所知,
SortedSet
是最好的结果。@AlexeiLevenkov是的,令人失望的是,他们没有O(log n)搜索方法来利用SortedSet的数据结构!值得一提的是,在执行BinarySearch之前,必须对列表进行排序——从msdn页面的备注部分可以看出:“列表必须已经根据比较器实现进行了排序;否则,结果是不正确的。”@zohar OP从SortedSet开始,因此此类集合上的ToList将生成排序列表。事实上,如果从其他数据开始,那么排序是第一步——但这比最初的线性搜索更糟糕。我完全同意你的观点,这就是为什么我对你的答案投了更高的票,但这也是我认为值得一提的——你的例子没有在有序集上使用
.ToList()
。。。
// starting sample for BinarySearch approach  
// not handling case where item not in the list (x = 1).
// List have to be sorted which is the case starting from sorted set: sortedSet.ToList()
var list = new List<int>{ 1,3, 5, 7, 8,9}; 
var index = list.BinarySearch(8);
Console.WriteLine(index < 0 ? list[~index - 1] : list[index-1]);