我有LIST<T> where T:IComparable<T>
我想写一个List<T> GetFirstNElements (IList<T> list, int n) where T :IComparable <T>
,它使用表达式树返回前n个不同的最大元素(列表可以有dupes)。
答案 0 :(得分:3)
在我最近写的一些性能关键代码中,我有一个非常相似的要求 - 候选集非常大,而且需要的数量非常小。为了避免对整个候选集进行排序,我使用了一个自定义扩展方法,该方法只保留链接列表中到目前为止找到的n个最大项。然后我可以简单地说:
public static IEnumerable<T> TakeTopDistinct<T>(this IEnumerable<T> source, int count)
{
if (source == null) throw new ArgumentNullException("source");
if (count < 0) throw new ArgumentOutOfRangeException("count");
if (count == 0) yield break;
var comparer = Comparer<T>.Default;
LinkedList<T> selected = new LinkedList<T>();
foreach(var value in source)
{
if(selected.Count < count // need to fill
|| comparer.Compare(selected.Last.Value, value) < 0 // better candidate
)
{
var tmp = selected.First;
bool add = true;
while (tmp != null)
{
var delta = comparer.Compare(tmp.Value, value);
if (delta == 0)
{
add = false; // not distinct
break;
}
else if (delta < 0)
{
selected.AddBefore(tmp, value);
add = false;
if(selected.Count > count) selected.RemoveLast();
break;
}
tmp = tmp.Next;
}
if (add && selected.Count < count) selected.AddLast(value);
}
}
foreach (var value in selected) yield return value;
}
答案 1 :(得分:0)
如果我的问题正确,您只想对列表中的条目进行排序
您是否可以实现IComparable并使用列表的“排序”方法?
“IComparable”中的代码可以处理树比较以及您想要用来比较和排序的所有内容,这样您就可以使用Sort mechnism。
List<T> GetFirstNElements (IList<T> list, int n) where T :IComparable <T>{
list.Sort();
List<T> returnList = new List<T>();
for(int i = 0; i<n; i++){
returnList.Add(list[i]);
}
return returnList;
}
不是最快的代码; - )
答案 2 :(得分:0)
这样做的标准算法,在预期时间O(list.Length)在维基百科中作为“quickfindFirstK”在此页面上:
http://en.wikipedia.org/wiki/Selection_algorithm#Selecting_k_smallest_or_largest_elements
这改善了@Marc Gravell的答案,因为无论n的值如何,它的预期运行时间在输入列表的长度上是线性的。