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

本文关键字:列表 数字 情况下 LINQ | 更新日期: 2023-09-27 18:07:40

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

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

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

实际上,您自己的代码并没有完成预期的工作。

方法文档假设FindMissing将发现Min中缺少的数字。列表的Max范围。相反,该方法实际上查找列表中第一个值和最后一个值之间缺失的数字。换句话说,在给定的示例中,我期望从1到31进行搜索。相反,该方法将搜索从6到28。


现在,如果您需要将其转换为非linq方法,请逐步尝试:

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

  2. 该方法使用Enumerable.Range。该行为很容易通过for循环重现。

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