【问题标题】:Create unique doubles and triplets from collection从收藏中创建独特的双胞胎和三胞胎
【发布时间】:2011-11-20 12:11:41
【问题描述】:

我有一个项目集合 (List) (String)。此集合中的项目数将始终介于 0 到 9 之间。

我需要从这个集合中创建对和三元组的所有组合。 双重或三重中项目的位置无关紧要。所以{1,2} 等于{2,1}

我怎样才能做到这一点?也许有一些不错的方法可以通过 LINQ 做到这一点?

【问题讨论】:

  • 不,这不是作业。它用于称为隐藏子集的数独求解方法。我确实需要查找可能性的所有组合(双打,三重)并测试这些双打/三重是否仅在给定行/单元格/正方形中的两个或三个单元格中。如果是,我发现了隐藏的对/三元组,并且可以减少这些单元格中的可能性。

标签: c# .net collections


【解决方案1】:

在下面的代码中,我使用 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", "B", "C", "D", "E", "F", "G", "H", "I", "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", "B", "C", "D", "E", "F", "G", "H", "I", "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();
    }
}

LinkedNode 类上实现IEnumerable&lt;string&gt; 应该很容易,或者将LinkedNodes 转换为List&lt;string&gt;HashSet&lt;string&gt;。请注意,如果顺序不重要,您可以删除行 orderby a, b.Value

【讨论】:

  • 谢谢,它看起来不错,但是 - 有没有办法通用地编写这个查询来处理任意数量的 n-tuplets(我希望它是正确的英文术语)?我的意思是 - 我提供整数 N 并根据 N 我得到结果的方法 - N=2:双打,N=3:三胞胎,N=4:四胞胎。
  • @VojtechRuzicka 这应该是一个不同的问题。
  • 是的,有,但是你希望得到什么样的对象?
  • 不错的伊莲。 @VojtechRuzicka:n 元组是 correct term
  • @Hogan 好的,让我们排除四边形及更高,但我认为如果我们留下双打和三胞胎,问是否有针对双打和三胞胎的通用解决方案而不是两种方法有很多共同的代码。虽然没有冒犯,但接受了答案,因为它解决了我的问题。只是指出可能的改进。
猜你喜欢
  • 2012-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
  • 2017-04-11
  • 1970-01-01
相关资源
最近更新 更多