在下面的代码中哪一个更有效调用resize或erase?
vector<int> a(5000);
//....
vector<int>::iterator it = remove(a.begin(),a.end(),8)
a.resize( std::distance(a.begin(),it));
//or
a.erase(it,a.end());
我认为这取决于重复元素的数量对吗?
答案 0 :(得分:5)
重复的数量相等,它们具有相同的复杂性。收缩向量时,resize
是根据erase
:
n3337,23.3.6.3 说:
void resize(size_type sz);
9效果:如果
sz <= size()
,相当于erase(begin() + sz, end())
; 。 [...]
答案 1 :(得分:2)
剖析器说什么?这显然可以从一个变化 实施到另一个(虽然只是一个常数 因素 - 要求复杂性相同)。
就此而言:剖析器显示你失去了太多 在这儿吗?写这个的惯用方法是:
a.erase( std::remove( a.begin(), a.end(), 8 ), a.end() );
除非剖析器清楚地说这是一个瓶颈,否则你 应该以惯用的方式编写它,以便C ++程序员 立即认识到发生了什么,不要浪费时间 认识到你正在做同样的事情,并想知道为什么 你没有以惯用的方式做到这一点。
答案 2 :(得分:1)
“我认为这取决于重复元素的数量对吗?”
不。 int
没有析构函数,因此1个重复或1000个没有区别。所有函数需要做的是设置正在使用的元素的新结束的内部记录。因此,remove()
的效果在此处是代价高昂的,而不是resize
/ erase
。 (即使有一个析构函数,它们也会循环调用它的相同数量的元素,几乎完全相同的时间)。
你几乎总是可以信任任何经验丰富的标准库实现,不要做一些愚蠢的事情,并且花费的时间远远超过必要的时间,所以鉴于行为是相同的 - 每个jrok的答案 - 除非你的探查者告诉你,否则没有理由进一步调查到。
iter != v.end()
迭代器实现为指针而没有end()
的较慢的开始+大小算术计算,也没有同样丑陋的特殊外壳,因此递增end-1迭代器会产生一些哨兵状态。