Without sorting the arr
array, but using a sorted additional collection containing the highest numbers found at any time:
double[] arr = new double[5] { 12.1, 5.9, 2.9, 6.8, 20.5 };
int num = 3;
var lst = new List<double>();
foreach (double n in arr)
{
if (lst.Count < num)
{
lst.Add(n);
lst.Sort();
}
else if (n >= lst[0])
{
lst[0] = n;
lst.Sort();
}
}
foreach (double n in lst)
{
Console.WriteLine(n);
}
Without using any sort, but simply using a find-the-index-of-the-lowest-element function:
static int LowestIndex(double[] dbl)
{
if (dbl.Length == 0)
{
return -1;
}
int minIx = 0;
for (int i = 1; i < dbl.Length; i++)
{
if (dbl[i] < dbl[minIx])
{
minIx = i;
}
}
return minIx;
}
then
double[] arr = new double[5] { 12.1, 5.9, 2.9, 6.8, 20.5 };
int num = 3;
var lst = new List<double>();
int minIx = -1;
foreach (double n in arr)
{
if (lst.Count < num)
{
lst.Add(n);
continue;
}
if (minIx == -1)
{
minIx = LowestIndex(arr);
}
if (n >= arr[minIx])
{
lst[minIx] = n;
minIx = -1;
}
}
foreach (double n in lst)
{
Console.WriteLine(n);
}
Similar to the previous, but instead of sorting the lst
list and considering the element at index [0]
to be the lowest, we use a LowestIndex
method... Note that to make everything more interesting, I "cache" when possible the LowestIndex
result.
Third way, similar to the first one: lst
is kept sorted "manually" (so when we add a new element to lst
, we add it in the "right" position to keep lst
sorted)... Much more complex :-) Note that I'm using List<T>.BinarySearch
that has a "very interesting" way of returning the index when no exact match is found.
double[] arr = new double[] { 30, 1, 1, 12.1, 5.9, 2.9, 6.8, 20.5 };
int num = 3;
var lst = new List<double>();
foreach (double n in arr)
{
int ix = lst.BinarySearch(n);
if (ix < 0)
{
ix = ~ix;
}
if (ix == 0 && lst.Count == num)
{
continue;
}
if (lst.Count == num)
{
lst.RemoveAt(0);
ix--;
}
lst.Insert(ix, n);
}
foreach (double n in lst)
{
Console.WriteLine(n);
}