【问题标题】:How to do a left join with STL vector and STL algorithms with time complexity better than O(n^2)?如何使用时间复杂度优于 O(n^2) 的 STL 向量和 STL 算法进行左连接?
【发布时间】:2011-03-04 15:54:52
【问题描述】:

我有 2 个向量,其中包含 Person(姓名、姓氏等)对象。我想取其中一个向量(我们将其命名为“大”),然后为该向量中的每个元素找到第二个(“小”)中的对应元素,并将“小”向量元素中的一些数据合并到“大”向量元素。此操作与 SQL 术语中的左连接非常相似,但对数据进行了额外的合并。最简单的方法是进行 2 个周期,但这会导致 O(n^2) 时间复杂度。我可以用 STL 算法做得更好吗?

【问题讨论】:

  • 如果您从vector 切换到multiset,可能会做得更好。使用 Boost.MultiIndex 你甚至可以得到 O(n)。
  • @larsmans: 或哈希表(通常需要注意哈希表的实际与理论渐近性能)。散列函数由“对应元素”的定义决定,即仅对您要加入的字段进行散列。

标签: c++ algorithm stl stl-algorithm


【解决方案1】:

如果您sort 小向量,则可以通过扫描大向量得到合并部分的 O(n log n) 并使用 binary_search 查找小向量中的元素。

【讨论】:

  • sort 部分也是 O(n lg n),所以总共 2×O(n lg n) = O(n lg n)。 +1。
【解决方案2】:

是的! 您可以在 O(nlogn) 时间复杂度内完成。对第二个向量进行排序,这需要 O(nlogn) 时间。对于第一个向量中的每个元素,使用二进制搜索(STL 具有 binary_search 算法)在第二个向量中找到对应的元素,并将数据合并到第一个向量中的元素。对于第一个向量中的每个元素,我们花费 O(logn) 时间。所以这种方法的运行时间复杂度是O(nlogn)。

【讨论】:

    【解决方案3】:

    如果您的列表不经常更改,您可以对两个列表进行排序,然后通过简单地遍历两个列表以线性时间进行合并。

    如果您的列表一直在变化,您最好对“小”容器进行排序,例如mapset。在这种情况下,只需在集合上为您要加入的大列表中的每个项目使用 find

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-03-04
      • 2013-07-25
      • 2015-05-25
      • 1970-01-01
      • 2019-12-13
      • 1970-01-01
      • 2019-12-09
      • 2015-06-12
      相关资源
      最近更新 更多