2

我在 IntExtensions 类中有两个方法来帮助生成下一个可用的增量值(它不在需要排除的现有整数列表中)。我认为我没有以最好的方式解决 NextIncrementalValueNotInList 方法,我想知道我是否可以更好地使用 linq 来返回下一个可用的 int?

public static bool IsInList(this int value, List<int> ListOfIntegers) {
    if (ListOfIntegers.Contains(value))
        return true;

    return false;
}

public static int NextIncrementalValueNotInList(this int value, 
                                                List<int> ListOfIntegers) {

        int maxResult;
        maxResult = ListOfIntegers.Max() + 1;

        for (int i = value; i <= maxResult; i++)
        {
            if (!(i.IsInList(ListOfIntegers)))
            {
                return i;
            }
        }
        return maxResult;
    }
4

3 回答 3

5

使用 linq,您的方法将如下所示:

return IEnumerable.Range(1, ListOfIntegers.Count + 1)
                  .Except(ListOfIntegers)
                  .First();
于 2013-10-30T09:45:17.390 回答
2

我猜它从1开始。

你也可以这样进行:

IEnumerable.Range(1, ListOfIntegers.Count)
           .Where(i => !ListOfIntegers.Contains(i))
           .Union(new []{ ListOfIntegers.Count + 1 })
           .First();
于 2013-10-30T09:31:36.623 回答
2

您实际上不需要计算该Max值 - 只需不断增加i,直到您找到列表中不存在的值,例如:

public static int NextIncrementalValueNotInList(this int value, 
  List<int> ListOfIntegers)
{
    int i = value;

    while(true)
    {
        if (!(i.IsInList(ListOfIntegers)))
        {
            return i;
        }
        i++;
    }
    return maxResult;
}

. 除此之外,我不确定您是否可以做更多的事情,除非:

  • ListOfIntegers保证是或需要排序的,或
  • ListOfIntegers实际上并不需要成为List<int>

如果第一个答案是否定的,而第二个答案是肯定的,那么您可以改用 a HashSet<int>,这可能会HashSet<T>通过允许您简单地使用自己的bool Contains(T)方法来提供更快的实现:

public static int NextIncrementalValueNotInList(this int value, 
  HashSet<int> ListOfIntegers) 
{
    int i = value;
    while(true)
    {
        if (!(ListOfIntegers.Contains(i))
        {
            return value;
        }
        i++;
    }
}

请注意,此版本还显示了如何取消Max检查。

虽然要小心过早的优化 - 如果您当前的实现足够快,那么我不会担心。您应该用极端情况和实际情况正确地对任何替代解决方案进行基准测试,看看是否真的有任何区别。

此外,您不想做的是使用我上面的建议,将您的列表变成HashSet每次通话的列表。我建议完全改变您对Listto的使用HashSet- 每次调用的任何零碎转换都将抵消任何潜在的性能优势,因为创建HashSet.

最后,如果您实际上并不期望整数列表中有太多碎片,那么 aHashSet可能与当前的 Linq 版本没有太大不同,因为无论如何它最终可能会做类似的工作量。

于 2013-10-30T09:43:10.130 回答