【问题标题】:Finding elements that are present in one set not the other查找存在于一组而不是另一组中的元素
【发布时间】:2009-12-02 01:38:21
【问题描述】:

我有两组 A 和 B。

A
--
1
2
6

B
--
1
2
3
4

当我将集合 A 与 B 进行比较时,当集合 B 与 A 进行比较时,我需要将值 6 作为输出,并将值 4 作为输出。

我想知道最好的算法是什么?我写了一个,但它有一个二次复杂度。它基本上迭代一组并在循环内迭代第二组以检查值是否存在。我觉得这效率低下。

上下文

我在 UI 中显示的数据库中有一组值。用户可以删除或添加新项目到列表中,然后按“保存更改”按钮,这会将所有更改保存到数据库。所以在这里我需要将新添加的项目插入到数据库中并删除删除的项目。

所以我通过了第一个集合,其中包含新添加的和已经存在的项目。我加载了另一个集合,它将包含数据库中的所有项目。现在,如果我应用上述算法将 Set A(新列表)与 Set B(数据库列表)进行比较,并获取存在于 SetA 中而不存在于 SetB 中的项目,我会得到所有新添加的项目。然后将 SetB 与 SetA 进行比较,并且 setB 中存在且 SetA 中不存在的所有项目都将被删除。我愿意接受有关更好算法的建议。

任何帮助都会很棒。

【问题讨论】:

    标签: algorithm set


    【解决方案1】:

    查看 Apache CollectionUtils,您可以在其中找到将操作设置为 Union、Intersection 或减法(您想要什么)

    【讨论】:

      【解决方案2】:

      在 Python 中

      >>> A=set((1,2,6))
      >>> B=set((1,2,3,4))
      >>> A-B
      set([6])
      >>> B-A
      set([3, 4])
      

      假设您没有内置集合类型
      伪代码:

      # This computes the items of B that are not in A
      a=hash(A)   # Hopefully you at least have some sort of hash type
      result=[]   #empty list
      for item in B:
          if item not in a:
              result.append(item)
      

      【讨论】:

      【解决方案3】:

      如果两个集合都已排序,则可以从两个集合的开头开始遍历它们,比较第一个元素以查看另一个集合中缺少哪些元素。这在线性时间内有效。

      对于未排序的集合,首先在 O(nlog(n)) 时间内对它们进行排序,然后在线性时间内比较它们,总时间复杂度为 O(nlog(n))。根据您的应用程序的详细信息,也可以始终保持集合排序,以便在需要时轻松比较它们。

      【讨论】:

      • 因为问题的语言专门引用“集合”,所以您无法对它们进行排序。集合是一种抽象数据类型,可以存储唯一值,没有任何特定顺序
      • @SteelSoul 集合抽象数据类型可以转换为有序集合类型。在实现算法时既抽象又具体。将其描述为“排序”对我来说似乎是合理的。
      【解决方案4】:

      Here 是微软的回答。不过在我看来 O(n2)

      class CompareLists
      {        
          static void Main()
          {
              // Create the IEnumerable data sources.
              string[] names1 = System.IO.File.ReadAllLines(@"../../../names1.txt");
              string[] names2 = System.IO.File.ReadAllLines(@"../../../names2.txt");
      
              // Create the query. Note that method syntax must be used here.
              IEnumerable<string> differenceQuery =
                names1.Except(names2);
      
              // Execute the query.
              Console.WriteLine("The following lines are in names1.txt but not names2.txt");
              foreach (string s in differenceQuery)
                  Console.WriteLine(s);
      
              // Keep the console window open in debug mode.
              Console.WriteLine("Press any key to exit");
              Console.ReadKey();
          }
      }
      /* Output:
           The following lines are in names1.txt but not names2.txt
          Potra, Cristina
          Noriega, Fabricio
          Aw, Kam Foo
          Toyoshima, Tim
          Guy, Wey Yuan
          Garcia, Debra
           */
      

      【讨论】:

        【解决方案5】:

        您可以将这两个集合放入平衡二叉树中。在一个集合中搜索另一个集合中的元素是O(log n)。因此,在一组中针对另一组搜索 n' 元素是 O(n' log n) 或只是 O(n log n)

        如果将两个集合都制成排序数组,您可以在O(n + n')O(n) 时间以步进方式遍历这两个数组,以确定任一集合中的元素是否丢失。

        【讨论】:

          【解决方案6】:

          如果您可以访问哈希集实现(我相信 Java、C# 和 Python 都有),您可以构造两个集合 A 和 B 并获取集合的差值。如果未定义集合差异,您可以迭代 A 的元素并检查 B 是否具有每个元素。哈希集是用哈希表实现的,因此它可以在线性时间内构建,并且可以在恒定时间内测试成员资格。这意味着总时间将与集合大小的总和成线性关系。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-22
            • 1970-01-01
            • 2011-10-06
            • 1970-01-01
            • 2016-07-27
            相关资源
            最近更新 更多