【问题标题】:ICollection - check if a collection contains an objectICollection - 检查集合是否包含对象
【发布时间】:2017-03-15 17:42:21
【问题描述】:

知道非泛型 ICollection 不提供 Contains 方法,那么检查给定对象是否已经在集合中的最佳方法是什么?

如果我有两个ICollections: A 和 B,并且想检查 B 是否包含 A 的所有元素,那么最好的方法是什么?我的第一个想法是将 A 的所有元素添加到 HashSet 中,然后使用 Contains 检查是否所有 B 的元素都在集合中。

【问题讨论】:

  • Cast->ToList->包含
  • @Nkosi 这比 OP 提出的解决方案要糟糕得多……
  • @Servy 仅仅停留在有效的地方是不够的,您需要了解更多以改进有效的解决方案。
  • @user5539357 如果您想对您的工作解决方案进行代码审查,请尝试 Code Review,尽管尝试对您的工作解决方案进行代码审查而不提供您的工作解决方案不是特别有帮助。仅仅要求人们重新创建您的工作解决方案对任何人都没有帮助,也不是该网站的目的。
  • 让我们回顾一下。问题陈述:当B包含A的所有元素时bool F(A, B)为真。给出的算法是:将A转换为集合,检查B的所有元素是否在A中。测试用例:A是{1},B是{1 , 2}。由于 B 包含 A 的所有元素,因此 F(A, B) 应该为真。算法是:检查B的所有元素是否都在A中。2是B的元素,2不在A中,因此,算法返回false。因此算法不正确。由于您认为您的算法是正确的,您还没有测试您的算法。测试一下!

标签: c# .net collections


【解决方案1】:

如果我有两个ICollections AB 并想检查B 是否包含A 的所有元素,那么最好的方法是什么?

让我用集合的语言重新表述你的问题。

如果我有两组 AB 并想检查 A 是否是 B 的子集,那么最好的方法是什么?

现在很容易看到答案:

https://msdn.microsoft.com/en-us/library/bb358446%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

A 构造一个HashSet<T>,然后使用IsSubsetOf 方法查看A 是否是B 的子集。

我注意到,如果这些是您必须经常执行的操作,那么您应该首先将数据保存在 HashSet<T> 集合中。如果两个集合都是哈希集,IsSubsetOf 操作可能更有效。

【讨论】:

  • 当两个集合都是HashSet 集合时,您获得性能提升的主要原因是它使Contains 查询在恒定时间内运行。如果您调用B.IsSupersetOf(A) 而不是A.IsSubsetOf(B),则无需从A 构造HashSet 即可获得此性能。
  • @Brian:好提示!
【解决方案2】:

A 和 B 并想检查 B 是否包含 A 的所有元素

我认为你有它倒退。将 B 添加到 HashSet。

HashSet.Contains 为 O(1)
总体而言,它将是 O(n + m)

假设字符串

  HashSet<string> HashSetB = new HashSet<string>(iCollecionB);
  foreach (string s in iCollecionA) 
  {
      if(HashSetB.Contains(s))
      {
      }
      else 
      {
      }
  }  

【讨论】:

    【解决方案3】:
    Boolean ICollectionContains(ICollection collection, Object item)
    {
       for (Object o in collection)
       {
          if (o == item)
             return true;
       }
       return false;
    }
    

    或以扩展形式:

    public static class CollectionExtensions
    {
       public static Boolean Contains(this ICollection collection, Object item)
       {
          for (Object o in collection)
          {
             if (o == item)
                return true;
          }
          return false;
       }
    }
    

    有用法:

    ICollection turboEncabulators = GetSomeTrunnions();
    
    if (turboEncabulators.Contains(me))
       Environment.FailFast(); //How did you find me!
    

    【讨论】:

    • 这仅使用引用相等,如果您想这样做,不妨使用collection.Cast&lt;object&gt;().Any(o =&gt; o == item)
    猜你喜欢
    • 1970-01-01
    • 2017-06-04
    • 2022-11-09
    • 2017-10-23
    • 1970-01-01
    • 2015-01-30
    • 2017-05-16
    • 2017-07-20
    • 2016-05-24
    相关资源
    最近更新 更多