如何从一组整数中找到最小的不同组?

时间:2013-01-15 16:51:51

标签: c# linq

假设我有一个课程如下......

public class IntGroup {
  public string GroupName {get; set;}
  public List<int> Integers {get; set;}
}

...我有几个实例,每个实例都包含一个整数集合。我想找到包含不同整数的最小组。

例如,如果我有以下组...

第1组包含1,2,3 第2组包含4,5,6 第3组包含4,5,9

...然后由于组1包含三个不在任何其他组中的整数,它本身就是一组最小的组(在本例中是一组)。第2组和第3组是另一组,因为你需要两个组在一起(因为它们都包含4和5),但它们不需要组1。

我想写一些C#代码,可以帮助我找到这些最小的组。这是我认为在Linq中可以非常优雅地解决的问题,但我无法弄清楚如何。

任何人都可以提供帮助吗?顺便说一句,这不是一个功课问题,我是一个51岁的程序员,希望解决一个更大问题的部分问题,即构建函数调用树,并希望找到树的不同部分。

感谢您提供任何帮助。

1 个答案:

答案 0 :(得分:2)

首先定义这个类:

class ValueIEnumerableComparer<T> : IEqualityComparer<IEnumerable<T>>
{
    public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
    {
        return x.SequenceEqual(y);
    }

    public int GetHashCode(IEnumerable<T> obj)
    {
        return obj.Sum(i => i.GetHashCode());
    }
}

然后,您可以使用此链:

int[][] groups =
{
    new[] {1, 2, 3}, 
    new[] {4, 5, 6},
    new[] {4, 5, 9}
};
var result = groups.
    GroupBy(array => groups.
        Where(other => array != other).
        SelectMany(other => array.Intersect(other)), 
            new ValueIEnumerableComparer<int>()).
    Select(g => g.ToArray()).
    ToArray();

它的作用是按照交叉点对数组进行分组,然后只选择组中的数组。定义实现IEqualityComparer<IEnumerable<T>>的类是必要的。我没有找到一种更好的方法来提取两个序列上的密钥,而没有定义比较它们的元素的比较器。它的GetHashCode()方法并不真实,但适用于此示例。

它也可以很容易地适应你的情况,但我认为带一个普通的对于那些阅读问题的人来说会更有帮助。