【问题标题】:Check if lists are disjoint检查列表是否不相交
【发布时间】:2018-06-07 13:24:27
【问题描述】:

我需要检查两个列表是否有任何共同的元素。 我只需要一个是/否 - 我不需要常见元素的实际列表。

我可以使用Enumerable.Intersect(),但这实际上会返回一组匹配项,这似乎需要额外的开销。 有没有更好的方法来检查列表是否不相交?


我的列表确实恰好是List<T>,但这并不重要,如果更方便的话,我可以使用类似HashSet(比如说)的东西。即,我不想不必要地限制潜在的解决方案。

千玺

【问题讨论】:

  • 在相交之后粘贴 .Any()。
  • Enumerable.Intersect().Any() 应该(无论如何,IIRC)在找到第一个相交出现后立即返回,而不是返回整个集合。

标签: c# disjoint-sets


【解决方案1】:

最简单的版本(使用相交):

 public bool Compare(List<T> firstCollection, List<T> secondCollection)
 {
    return firstCollection.Intersect(secondCollection).Any();
 }

唯一需要注意的是T 应实现IEquatable&lt;T&gt; 或在Intersect 调用中传递自定义IEqualityComparer&lt;T&gt;。还要确保GetHashCodeEquals 一起被覆盖

编辑 1:

这个使用 Dictionary 的版本不仅会提供boolean 的比较,还会提供元素。在这个解决方案中,Dictionary 最终将包含与相交元素数量、一个集合中的元素数量而不是另一个集合中的元素数量相关的数据,因此相当耐用。此解决方案还具有IEquatable&lt;T&gt; 要求

public bool CompareUsingDictionary(IEnumerable<T> firstCollection, IEnumerable<T> secondCollection)
    {
        // Implementation needs overiding GetHashCode methods of the object base class in the compared type
        // Obviate initial test cases, if either collection equals null and other doesn't then return false. If both are null then return true.
        if (firstCollection == null && secondCollection != null)
            return false;
        if (firstCollection != null && secondCollection == null)
            return false;
        if (firstCollection == null && secondCollection == null)
            return true;

        // Create a dictionary with key as Hashcode and value as number of occurences
        var dictionary = new Dictionary<int, int>();

        // If the value exists in first list , increase its count
        foreach (T item in firstCollection)
        {
            // Get Hash for each item in the list
            int hash = item.GetHashCode();

            // If dictionary contains key then increment 
            if (dictionary.ContainsKey(hash))
            {
                dictionary[hash]++;
            }
            else
            {
                // Initialize he dictionary with value 1
                dictionary.Add(hash, 1);
            }
        }

        // If the value exists in second list , decrease its count
        foreach (T item in secondCollection)
        {
            // Get Hash for each item in the list
            int hash = item.GetHashCode();

            // If dictionary contains key then decrement
            if (dictionary.ContainsKey(hash))
            {
                dictionary[hash]--;
            }
            else
            {
                return false;
            }
        }

        // Check whether any value is 0
        return dictionary.Values.Any(numOfValues => numOfValues == 0);
    }

【讨论】:

    猜你喜欢
    • 2017-12-09
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多