C# 以创建可枚举项和使用降序排序所有内容的成本为代价。我说可以,就像源不是内存中的列表而是可查询的一样。我在第三个块中没有看到可为null的int技巧。尽管现在这似乎不是一个高性能的解决方案,因为它首先创建列表的一个副本,然后在LINQ表达式中生成一个可枚举项
C# 以创建可枚举项和使用降序排序所有内容的成本为代价。我说可以,就像源不是内存中的列表而是可查询的一样。我在第三个块中没有看到可为null的int技巧。尽管现在这似乎不是一个高性能的解决方案,因为它首先创建列表的一个副本,然后在LINQ表达式中生成一个可枚举项,c#,list,linq,sorting,C#,List,Linq,Sorting,以创建可枚举项和使用降序排序所有内容的成本为代价。我说可以,就像源不是内存中的列表而是可查询的一样。我在第三个块中没有看到可为null的int技巧。尽管现在这似乎不是一个高性能的解决方案,因为它首先创建列表的一个副本,然后在LINQ表达式中生成一个可枚举项。您可以在一行中将其ram在一起。然而,这种转换将更加微妙。此答案不包括性能调整,因为它不是问题的一部分。请参阅我发布的两个答案,其中涵盖了列表本身为null或其上的元素少于5个时的情况。这是一个非常好的大型数据集解决方案,非常感谢您的贡献+1
以创建可枚举项和使用降序排序所有内容的成本为代价。我说可以,就像源不是内存中的列表而是可查询的一样。我在第三个块中没有看到可为null的int技巧。尽管现在这似乎不是一个高性能的解决方案,因为它首先创建列表的一个副本,然后在LINQ表达式中生成一个可枚举项。您可以在一行中将其ram在一起。然而,这种转换将更加微妙。此答案不包括性能调整,因为它不是问题的一部分。请参阅我发布的两个答案,其中涵盖了列表本身为
null
或其上的元素少于5个时的情况。这是一个非常好的大型数据集解决方案,非常感谢您的贡献+1。需要澄清的一个问题是:该算法是否会对列表进行排序,直到找到第k个排序元素,然后退出?@sɐunıןqɐp是的,实际上是这样的(因此通常会显著减少工作量)。预期的复杂性是O(n+k log k)
——但是,请注意,最坏的情况可能非常糟糕(我链接的维基百科文章中提到了这一点)。
List<int> list = new List<int>();
list.Add(2);
list.Add(18);
list.Add(21);
list.Add(10);
list.Add(20);
list.Add(80);
list.Add(23);
list.Add(81);
list.Add(27);
list.Add(85);
int fifth = list.OrderByDescending(x => x).Skip(4).First();
int result;
if(list != null && list.Count >= 5)
{
list.Sort();
result = list[list.Count - 5];
}
else // define behavior when list is null OR has less than 5 elements
List<int> copy = new List<int>(original);
List<int> copy = original.ToList();
int fifth;
try
{
fifth = list.OrderByDescending(x => x).ElementAt(4);
}
catch (ArgumentOutOfRangeException)
{
//Handle the exception
}
int fifth = list.OrderByDescending(x => x).ElementAtOrDefault(4);
if (fifth == 0)
{
//handle default
}
var newList = list.Select(i => (int?)i).ToList();
int? fifth = newList.OrderByDescending(x => x).ElementAtOrDefault(4);
if (fifth == null)
{
//handle default
}
int fifth = list?.Count >= 5 ?
list.OrderByDescending(x => x).Take(5).Last() :
throw new Exception("list is null OR has not enough elements");
int? fifth = list?.Count >= 5 ?
list.OrderByDescending(x => x).Take(5).Last() :
default(int?);
if(fifth == null) // define behavior
if(list == null || list.Count <= 0)
throw new Exception("Unable to retrieve Nth biggest element");
int fifth = list.OrderByDescending(x => x).Take(5).Last();
public static class QuickHelpers
{
// Put the code here
}
int resA = list.QuickSelect(2, (x, y) => Comparer<int>.Default.Compare(y, x));
int resB = list.QuickSelect(list.Count - 1 - 2);
public static IList<T> PartialSort<T>(IList<T> data, int k) where T : IComparable<T>
{
int start = 0;
int end = data.Count - 1;
while (end > start)
{
var index = partition(data, start, end);
var rank = index + 1;
if (rank >= k)
{
end = index - 1;
}
else if ((index - start) > (end - index))
{
quickSort(data, index + 1, end);
end = index - 1;
}
else
{
quickSort(data, start, index - 1);
start = index + 1;
}
}
return data;
}
static int partition<T>(IList<T> lst, int start, int end) where T : IComparable<T>
{
T x = lst[start];
int i = start;
for (int j = start + 1; j <= end; j++)
{
if (lst[j].CompareTo(x) < 0) // Or "> 0" to reverse sort order.
{
i = i + 1;
swap(lst, i, j);
}
}
swap(lst, start, i);
return i;
}
static void swap<T>(IList<T> lst, int p, int q)
{
T temp = lst[p];
lst[p] = lst[q];
lst[q] = temp;
}
static void quickSort<T>(IList<T> lst, int start, int end) where T : IComparable<T>
{
if (start >= end)
return;
int index = partition(lst, start, end);
quickSort(lst, start, index - 1);
quickSort(lst, index + 1, end);
}
PartialSort(list, 5);
Console.WriteLine(list[4]);