在LINQ语句中,什么是N-可枚举集合?

5
可能是重复问题:
生成所有可能的组合 我不确定如何表达这个问题,但我在解决一个愚蠢的逻辑谜题时使用了一个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})

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

我尝试过几次,但我真的看不出如何做到这一点。有人能指点我吗?


4
Eric Lippert曾经在他的博客中讨论过如何使用LINQ计算多个序列的笛卡尔积,这可能会对你有所帮助。 - Anthony Pegram
@AnthonyPegram - 非常完美。正是我所需要的。如果你想把它作为答案发布,我会接受它。 - Rob P.
这不是我的答案。 ;) 如果你想要给出应有的荣誉,请在这里尝试 - Anthony Pegram
1个回答

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接