【发布时间】:2011-09-27 14:35:06
【问题描述】:
根据this page,如果我使用我可以实现恒定时间插入
iterator std::set::insert ( iterator position, const value_type& x );
我直接提供的 position 迭代器“先于”正确的(按顺序)插入点。
现在我关心的情况是,如果我知道我插入的值在最后(因为它是最大的),例如:
set<int> foo = {1, 2, 3};
foo.insert(4); // this is an inefficient insert
根据上述标准,我应该将最后一个元素 foo.end()-1 传递给 insert 不 foo.end()。我的理解正确吗?如果我通过foo.end() 会发生什么?是O(log n) 插入还是O(1) 插入。所以,选项是:
// Option A
foo.insert(foo.end()-1, 4);
// Option B
foo.insert(foo.end(), 4);
// Safer version of Option A
if(foo.empty())
foo.insert(4);
else
foo.insert(foo.end()-1, 4);
我问是因为我正在编写一个在容器上模板化的函数。我想在传入的任何容器的末尾插入一个元素(我知道它是最大的)。使用上面的“选项 A”对于像 vector 这样的容器有不同的行为:
foo.insert(foo.end()-1, 4);
// result is {1, 2, 3, 4} if foo is an std::set
// result is {1, 2, 4, 3} if foo is an std::vector
正如@Bo_Persson 所暗示的,这里的问题是 C++03 说“一般是对数,但如果 t 在 p 之后插入,则为摊销常数”。而 C++0x 表示“一般是对数,但如果 t 插入到 p 之前,则为摊销常数。”
PS:我在启用了 C++0x 支持的 Ubuntu 11.04 上使用 GCC 4.5。
编辑:我在启用和禁用 C++0x 支持以及 posted the results in an answer 的情况下运行了经验测试。基本上,结论是提供end() 作为插入提示同样好(而且显然更安全)。然而,这显然只是一个经验观察。如前所述,该标准在这方面仍然令人困惑。
【问题讨论】:
标签: c++ stl insert set complexity-theory