【问题标题】:Complexity of inserting sorted range into associative container将排序范围插入关联容器的复杂性
【发布时间】:2012-07-07 00:54:00
【问题描述】:

标准规定(23.4.4.2:5 等)从范围 [first, last) 构造所有四个有序关联容器(mapmultimapsetmultiset)应是线性的N = last - first 如果范围已经排序。

但是,为了将范围(例如相同类型的容器)合并到现有容器中,23.2.4:8 表 102 仅指定 insert将范围 [i, j) 合并到容器中应具有复杂性 @987654330 @ 其中N = distance(i, j)。这似乎表明使用提示插入:

for (auto it = a.begin(); i != j; ++i)
    it = next(a.insert(it, *i));

可能比a.insert(i, j) 更有效,复杂度严格低于N log(a.size() + N),具体取决于正确提示的比例(N == 0 的小例子除外);并且是线性,因为每个提示都是正确的,如果a 最初是空的。

这是标准的缺陷,还是有其他语言(或工具)涵盖了这种情况?在实践中,实现是否针对将有序关联容器合并到另一个容器进行了优化?

感谢 https://stackoverflow.com/a/11362162/567292 提出这个问题。

【问题讨论】:

  • +1 当我读到“鼓舞人心”的答案时,我也在想同样的事情。
  • 如果你最后一部分的答案是“是”,那么激发它的问题的答案可能是使用我的第一个代码 sn-p。这会很好,因为它也是最简单的:-)

标签: c++ standards complexity-theory associative-array


【解决方案1】:

我会假设在后一种情况下,该标准仅指定关联容器合并的最坏情况保证的运行时性能,如果可能的话,让实现来寻找更快的性能捷径。请记住,与其他语言不同,C++ 规范正是如此——一个规范。没有“参考”实现。因此,可以编写一个只满足某些性能标准的实现,或者可以决定实现超过指定性能标准的特性。最后,尽管该规范旨在以某些算法的实现方式为您提供“至少”性能保证。

话虽如此,如果您总是对每个元素都使用提示,那么您在最坏情况下的性能实际上最终会比您在没有提示的情况下简单地插入慢两倍。所以总是使用提示不一定是灵丹妙药。

【讨论】:

  • 另外,从排序列表构建平衡树非常简单和容易。合并两棵树不是。
  • 因为对于每个元素 N,您最终都会遍历被合并为两次的树。
猜你喜欢
  • 1970-01-01
  • 2014-10-10
  • 2011-09-01
  • 2021-05-30
  • 2013-11-18
  • 2018-09-22
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多