我有一个项目的集合(列表)(字符串).此集合中的项目数始终介于0到9之间.
我需要从这个集合中创建对和三元组的所有组合.
物品在双重或三重中的位置无关紧要.所以{1,2}等于{2,1}.
我怎样才能实现这一目标?也许有一些很好的方法通过LINQ做到这一点?
解决方法
在下面的代码中,我使用
linq生成所有唯一的双精度和三元组.我使用字符串总排序的事实.
这会产生所有双打:
string[] items = { "A","B","C","D","E","F","G","H","I","J" }; var combinations = from a in items from b in items where a.CompareTo(b) < 0 orderby a,b select new { A = a,B = b }; foreach(var pair in combinations) Console.WriteLine("({0},{1})",pair.A,pair.B);
这会生成所有三元组:
string[] items = { "A","J" }; var combinations = from a in items from b in items from c in items where a.CompareTo(b) < 0 && b.CompareTo(c) < 0 orderby a,b,c select new { A = a,B = b,C = c }; foreach(var triplet in combinations) Console.WriteLine("({0},{1},{2})",triplet.A,triplet.B,triplet.C);
更新:有一个通用的解决方案来创建特定长度的所有唯一子集,仍然使用linq.但是,您需要一个可以包含子集的返回类型.我创建了一个简单的类LinkedNode,因为对我而言,这与linq结合起来感觉最自然:
void Main() { string[] items = { "A","J" }; foreach(var combination in CreateCombinations(items,5)) Console.WriteLine("({0})",combination.ToString()); } private static IEnumerable<LinkedNode> CreateCombinations(string[] items,int length) { if(length == 1) return items.Select(item => new LinkedNode { Value = item,Next = null }); return from a in items from b in CreateCombinations(items,length - 1) where a.CompareTo(b.Value) < 0 orderby a,b.Value select new LinkedNode<T> { Value = a,Next = b }; } public class LinkedNode { public string Value { get; set; } public LinkedNode Next { get; set; } public override string ToString() { return (this.Next == null) ? Value : Value + "," + Next.ToString(); } }
应该很容易实现IEnumerable< string>在LinkedNode类上,或以其他方式将LinkedNodes转换为List< string>或HashSet< string>.请注意,如果订单不重要,您可以删除a,b.Value的行顺序.