2012-02-01 61 views
5

可能重複:
Generating all Possible CombinationsN-Enumerables在LINQ聲明中?

我不知道如何短語的問題;但我正在研究一個愚蠢的邏輯謎題,我可以使用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值而不是4來做同樣的事情。例如,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

埃裏克利珀[博客上這個(http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian- product-with-linq.aspx)關於計算許多序列的產品。它可能有幫助。 – 2012-02-01 20:52:01

+0

@AnthonyPegram - 這是完美的。正是我在找什麼。如果你想發佈這個答案,我會接受它。 – 2012-02-01 20:55:14

+0

這不是我的*答案。 ;)如果您希望在信用到期時給予抵免,請[嘗試此處](http://stackoverflow.com/a/3098381/414076) – 2012-02-01 20:56:57

回答

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