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;
}
}
现在您可以通过以下方式调用扩展方法:
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);
}
}
}
答案 0 :(得分:2)
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;
}
当然,这可能会优化,不会每次都遍历整个listClone
答案 1 :(得分:2)
实际上,您自己的代码没有按预期执行。
方法文档假装FindMissing
会查找列表中Min
.. Max
范围内缺少的数字。相反,该方法实际上在列表中的第一个和最后一个值之间找到缺失的数字。换句话说,在给定的示例中,我希望搜索从1到31完成。相反,该方法将从6到28进行搜索。
现在,如果您需要将其转换为非LINQ方法,请逐步尝试:
该方法使用list.First()
和list.Last()
。您可以使用索引和list.Count
来获得这两个值。
该方法使用Enumerable.Range
。使用for
循环可轻松复制该行为。
该方法使用IEnumerable.Except()
。您可以通过遍历列表来自行查找缺失值。