Ala*_*ing 11 c++ complexity-theory stl insert set
根据这个页面,如果我使用,我可以实现恒定时间插入
iterator std::set::insert ( iterator position, const value_type& x );
Run Code Online (Sandbox Code Playgroud)
position
我提供的迭代器直接"在"正确(有序)插入点之前.
现在我关心的情况是,如果我知道我插入的值最后(因为它是最大的),例如:
set<int> foo = {1, 2, 3};
foo.insert(4); // this is an inefficient insert
Run Code Online (Sandbox Code Playgroud)
根据上述标准,我应该将最后一个元素传递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);
Run Code Online (Sandbox Code Playgroud)
我问,因为我正在编写一个在容器上模板化的函数.我想在传入任何容器的末尾插入一个元素(我知道是最大的).使用上面的"选项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
Run Code Online (Sandbox Code Playgroud)
正如@Bo_Persson所暗示的,这里的问题是C++ 03说"一般是对数,但如果在p之后插入t,则摊销常数." 而C++ 0x表示"一般为对数,但如果在p之前插入t,则摊销常数."
PS:我在Ubuntu 11.04上使用GCC 4.5并启用了C++ 0x支持.
编辑:我运行经验测试,启用和禁用C++ 0x支持,并将结果发布到答案中.基本上,结论是提供end()
插入提示同样好(并且显然更安全).然而,这显然只是一个经验观察.如上所述,标准在这方面仍然令人困惑.
运行测试而不阅读库规范是作弊吗?
对于g++-4.4 -O2
整数,0 <= i < 5000000
我的标准插入运行时间是
real 0m14.952s
user 0m14.665s
sys 0m0.268s
Run Code Online (Sandbox Code Playgroud)
我使用end()
提示插入的运行时间是
real 0m4.373s
user 0m4.148s
sys 0m0.224s
Run Code Online (Sandbox Code Playgroud)
据我所知,插入 at 的end() - 1
速度最快,但使用起来比较麻烦,因为它是end() - 1
非法操作(您必须使用operator--()
),并且如果集合碰巧为空,它就会崩溃。
#include <set>
typedef std::set<int> Set;
void insert_standard(Set& xs, int x)
{
xs.insert(x);
}
void insert_hint_end(Set& xs, int x)
{
xs.insert(xs.end(), x);
}
int main()
{
const int cnt = 5000000;
Set xs;
for (int i = 0; i < cnt; i++) {
// insert_hint_end(xs, i);
insert_standard(xs, i);
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1066 次 |
最近记录: |