LINQ声明中的N-Enumerables?

时间:2012-02-01 20:48:56

标签: c# linq combinations

  

可能重复:
  Generating all Possible Combinations

我不确定如何说出这个问题;但我正在研究一个愚蠢的逻辑谜题,我能够使用LINQ语句来解决。相关代码如下所示:

(from myA in Enumerable.Range(1, 40)
 from myB in Enumerable.Range(1, 40)
 from myC in Enumerable.Range(1, 40)
 from myD in Enumerable.Range(1, 40)
 where myA + myB + myC + myD == 40
    && myA <= myB
    && myB <= myC
    && myC <= myD
 select new[] {myA, myB, myC, myD})

所以它基本上生成满足Where子句中标准的A,B,C D的所有组合。

我现在要做的是概括这一点,所以我可以用N值而不是四个来做同样的事情。例如,有3个值 - 等效代码为:

(from myA in Enumerable.Range(1, 40)
 from myB in Enumerable.Range(1, 40)
 from myC in Enumerable.Range(1, 40)
 where myA + myB + myC == 40
    && myA <= myB
    && myB <= myC
 select new[] {myA, myB, myC})

当然,我不想修改代码 - 我想要一个我可以调用的函数并提供一个整数并让它返回正确的对象。

我做了一些误入歧途的尝试;但我真的看不出怎么做那样的事。有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:0)

没有阅读链接,我不确定这是否是正确的方法,但为什么不能想象我们正在走一棵深度为n的树,每个节点都有40个(或者在示例中为20个) ?它看起来像这样,然后:

class Program {
    static void Main(string[] args) {
        Walk(3).Where(l => l.Sum() == 20 &&
            l.Skip(1).Where((num, i) => num < l[i]).Count() == 0)
        .ToList().ForEach(l => Console.WriteLine(string.Join(" ", l)));
        Console.ReadLine();
    }

    static IEnumerable<List<int>> Walk(int depth) {
        return depth == 0 ? 
            new[] { new List<int>()} :
            Enumerable.Range(1,20).SelectMany(i =>
                Walk(depth - 1).Select(l => l.Concat(new[] {i}).ToList()));
    }
}