轉載請留出處《http://www.cnblogs.com/localhost2016/p/8668355.html》
組個例子:用戶選擇穿衣服組合方案。這個組合方案怎么生成
string[] a = {"帽子1",“帽子2”,“帽子3”};
string[] b = {"外套1",“外套2”};
string[] c ={"褲子1",“褲子2“,“褲子3”,“褲子4”};
string[] d ={"鞋子1",“鞋子2”,“鞋子3”};
起初實現很簡單,就是用循環得到所要的組合字符串。但是稍微一變動,哪怕僅僅是類型的改變,就歇菜了。下面我給出我實現的方式。
1 public static class EnumerableEx 2 { 3 /// <summary> 4 /// 從集合中的選出K個元素組合數 5 /// </summary> 6 public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> sequences, int k) 7 { 8 return k == 0 ? new[] { new T[0] } : sequences.SelectMany((e, i) => 9 sequences.Skip(i + 1) 10 .Combinations(k - 1) 11 .Select(c => (new[] { e }).Concat(c)) 12 ); 13 } 14 /// <summary> 15 /// 求集合的笛卡爾積 16 /// </summary> 17 public static IEnumerable<IEnumerable<T>> Cartesian<T>(this IEnumerable<IEnumerable<T>> sequences) 18 { 19 IEnumerable<IEnumerable<T>> tempProduct = new[] { Enumerable.Empty<T>() }; 20 return sequences.Aggregate(tempProduct, 21 (accumulator, sequence) => 22 from accseq in accumulator 23 from item in sequence 24 select accseq.Concat(new[] { item }) 25 ); 26 } 27 }
調用例子:
組合:從7個元素中選出3個元素。
1 string[] are = { "1", "2", "3", "4", "5", "6", "7" }; 2 var cc = are.Combinations(3); 3 foreach (var c in cc) 4 { 5 Console.WriteLine(string.Join("_", c)); 6 }
笛卡爾積:
List<List<string>> items = new List<List<string>>() { new List<string>(){ "a1","a2","a3"}, new List<string>(){ "b4","b5"}, new List<string>(){ "c6" } }; foreach (var item in items.Cartesian()) { Console.WriteLine(string.Join(",",item)); }