繁体   English   中英

使用LINQ生成数字序列

[英]Generate number sequences with LINQ

我尝试编写一个LINQ语句,它返回所有可能的数字组合(我需要这个测试,我的灵感来自Eric Lippert的这篇文章 )。 我调用的方法原型如下:

IEnumerable<Collection<int>> AllSequences( int start, int end, int size );

规则是:

  • 所有返回的集合都有一个size的长度
  • 集合中的数字值必须增加
  • 应该使用startend之间的每个数字

所以调用AllSequences( 1, 5, 3 )应该会产生10个集合,每个集合大小为3:

1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4 
2 3 5
2 4 5 
3 4 5

现在,不知怎的,我真的很想看到纯粹的LINQ解决方案。 我可以自己编写非LINQ解决方案,所以请不要在没有LINQ的情况下投入解决方案。
到目前为止,我的尝试已经结束,我必须加入一个数字与我的方法的递归调用的结果 - 如下所示:

return from i in Enumerable.Range( start, end - size + 1 )
       select BuildCollection(i, AllSequences( i, end, size -1));

但我无法管理它在LINQ基础上实现BuildCollection() - 甚至跳过此方法调用。 你能帮帮我吗?

 Enumerable.Range(1, 12)
           .Select(x => (x - 1) + 1);

我想我已经知道了。

IEnumerable<List<int>> AllSequences(int start, int end, int size)
{
    if (size == 0)
        return Enumerable.Repeat<List<int>>(new List<int>(), 1);

    return from i in Enumerable.Range(start, end - size - start + 2)
           from seq in AllSequences(i + 1, end, size - 1)
           select new List<int>{i}.Concat(seq).ToList();
}

我认为,像下面这样的事情应该可以胜任。

public static IEnumerable<IEnumerable<int>> AllSequences(int start, int end,
    int size)
{
    return size <= 0 ? new[] { new int[0] } :
           from i in Enumerable.Range(start, end - size - start + 2)
           from seq in AllSequences(i + 1, end, size - 1)
           select Enumerable.Concat(new[] { i }, seq);
}

解决方案的关键是复合from子句 ,这对于处理嵌套的可枚举非常方便。

请注意,我已将方法签名稍微更改为IEnumerable<IEnumerable<int>> ,因为使用(纯)LINQ时更方便。 但是,如果您愿意,可以随时将其轻松转换为IEnumerable<ICollection<int>>

如果代码需要任何解释,请告诉我,但我希望LINQ语法能够让它变得相当清楚。

编辑1:修复了错误并提高了简洁性。

编辑2:因为我很无聊并且没有更好的事情要做(不,不是真的),我想我会编写一个扩展方法来计算给定元素列表的组合,利用AllSequences方法。

public static IEnumerable<IEnumerable<T>> Combinations<T>(this IList<T> source,
    int num)
{
    return AllSequences(0, source.Count - 1, num).Select(
        seq => seq.Select(i => source[i]));
}

也许不是最有效的计算组合方式,但肯定是非常紧凑的代码!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM