标准指定(23.4.4.2:5等)从一个构建所有四个有序关联容器(map
,multimap
,set
,multiset
)如果范围已经排序,范围[first, last)
在N = last - first
中应该是线性的。
但是,为了将范围(例如,相同类型的容器)合并到现有容器中,23.2.4:8表102仅指定容器中insert
范围[i, j)
复杂度为N log(a.size() + N)
,其中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
最初是空的。
这是标准中的缺陷,还是有其他语言(或设施)涵盖此案例?在实践中,实现是否优化以将有序关联容器合并到另一个?
答案 0 :(得分:1)
我认为在后一种情况下,标准仅指定了关联容器合并的最坏情况保证运行时性能,如果可能的话,将其留给实现以找到更快的性能快捷方式。请记住,与其他语言不同,C ++规范正是如此 - 一个规范。没有“参考”实施。因此,可以编写仅满足某些性能标准的实现,或者可以决定实现超出指定性能标准的功能。最后,虽然规范旨在为您提供某些算法实现方式的“至少”性能保证。
话虽这么说,如果你总是对每个元素使用提示,那么你的最坏情况表现实际上最终会比你没有暗示插入时慢两倍。因此,始终使用暗示并不一定是灵丹妙药。