如何在不使用LINQ的情况下在列表中找到缺失的数字?

时间:2011-09-05 09:27:45

标签: c# linq

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);
        }
    }
}

2 个答案:

答案 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方法,请逐步尝试:

  1. 该方法使用list.First()list.Last()。您可以使用索引和list.Count来获得这两个值。

  2. 该方法使用Enumerable.Range。使用for循环可轻松复制该行为。

  3. 该方法使用IEnumerable.Except()。您可以通过遍历列表来自行查找缺失值。