如何使用不同的元素创建HashSet <List <Int >>?

Pre*_*ets 7 c# collections hashset distinct-values

我有一个包含多个整数列表的HashSet - 即 HashSet<List<int>>

为了保持唯一性,我目前不得不做两件事:1.手动循环现有列表,查找重复项SequenceEquals.2.对各个列表进行排序,使其SequenceEquals当前正常工作.

有一个更好的方法吗?是否存在可以提供给HashSet的现有IEqualityComparer,以便HashSet.Add()可以自动处理唯一性?

var hashSet = new HashSet<List<int>>();

for(/* some condition */)
{
    List<int> list = new List<int>();

    ...

    /* for eliminating duplicate lists */

    list.Sort();

    foreach(var set in hashSet)
    {
        if (list.SequenceEqual(set))
        {
            validPartition = false;
            break;
        }
    }

    if (validPartition)
           newHashSet.Add(list);
}
Run Code Online (Sandbox Code Playgroud)

谢谢 !

Han*_*ant 5

这开始是错误的,它必须是a,HashSet<ReadOnlyCollection<>>因为您不能允许列表更改并使集合谓词无效。然后,当您将集合添加到集合中时,就可以使用O(n)计算哈希码。然后进行O(n)测试以检查它是否已经存在于集合中,这是非常不常见的O(n ^ 2)最坏情况(如果所有散列都相等)。将计算出的哈希值与集合一起存储。


Cod*_*aos 5

这是一个可能的比较器,IEnumerable<T>它按元素比较 an 。您仍然需要在添加之前手动排序。

可以将排序构建到比较器中,但我认为这不是一个明智的选择。添加列表的规范形式似乎更明智。

此代码仅适用于 .net 4,因为它利用了通用差异。如果您需要早期版本,则需要替换IEnumerableList,或者为集合类型添加第二个泛型参数。

class SequenceComparer<T>:IEqualityComparer<IEnumerable<T>>
{
    public bool Equals(IEnumerable<T> seq1,IEnumerable<T> seq2)
    {
        return seq1.SequenceEqual(seq2);
    }

    public int GetHashCode(IEnumerable<T> seq)
    {
        int hash=1234567;
        foreach(T elem in seq)
            hash=hash*37+elem.GetHashCode();
        return hash;
    }
}

void Main()
{
    var hashSet = new HashSet<List<int>>(new SequenceComparer<int>());

    List<int> test=new int[]{1,3,2}.ToList();
    test.Sort();
    hashSet.Add(test);

    List<int> test2=new int[]{3,2,1}.ToList();
    test2.Sort();       
    hashSet.Contains(test2).Dump();
}
Run Code Online (Sandbox Code Playgroud)