C# 用Linq的方式實現組合和笛卡爾積(支持泛型T)


轉載請留出處《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));
            }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM