How can I find missing numbers in a list without using LINQ? [closed]
public static class MyExtensions
{
/// <summary>
/// Finds the missing numbers in a list.
/// </summary>
/// <param name="list">List of numbers</param>
/// <returns>Missing numbers</returns>
public static IEnumerable<int> FindMissing(this List<int> list)
{
// Sorting the list
list.Sort();
// First number of the list
var firstNumber = list.First();
// Last number of the list
var lastNumber = list.Last();
// Range that contains all numbers in the interval
// [ firstNumber, lastNumber ]
var range = Enumerable.Range(firstNumber, lastNumber - firstNumber);
// Getting the set difference
var missingNumbers = range.Except(list);
return missingNumbers;
}
}
N开发者_StackOverflow中文版ow you can call the extension method in the following way:
class Program
{
static void Main(string[] args)
{
// List of numbers
List<int> daysOfMonth =
new List<int>() { 6, 2, 4, 1, 9, 7, 3, 10, 15, 19, 11, 18, 13, 22, 24, 20, 27, 31, 25, 28 };
Console.Write("\nList of days: ");
foreach(var num in daysOfMonth)
{
Console.Write("{0} ", num);
}
Console.Write("\n\nMissing days are: ");
// Calling the Extension Method in the List of type int
foreach(var number in daysOfMonth.FindMissing())
{
Console.Write("{0} ", number);
}
}
}
public static IEnumerable<int> FindMissing(List<int> list)
{
if (list.Count < 3) yield break;
List<int> listClone = new List<int>(list); //do not modify the original list
listClone.Sort();
for (int n = listClone[i] ; n < listClone[listClone.Count - 1]; n++)
if (!listClone.Contains(n))
yield return n;
}
And of course this may be optimized not to traverse the entire listClone
every time
Actually, your own code is not doing what it is expected to do.
The method documentation pretends that FindMissing
will find what numbers are missing from Min
..Max
range of a list. Instead, the method actually finds the missing numbers between the first and the last value in a list. In other words, in a given example, I expect the search to be done from 1 to 31. Instead, the method will search from 6 to 28.
Now, if you need to transform this into a non-LINQ method, try it step by step :
The method uses
list.First()
andlist.Last()
. You can have both values by using indexes andlist.Count
.The method uses
Enumerable.Range
. The behavior is easily reproduced with afor
loop.The method uses
IEnumerable.Except()
. You can find the missing values yourself by looping through the list.
精彩评论