2014-02-17 40 views
0

在下面的代码中哪一个更有效地调用调整大小或擦除?哪一个更快使用擦除或调整矢量大小?

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()); 

我认为这取决于重复元素的数量吧?

+1

这两者都不是最理想的,因为需要'vector'来保持数据连续:一个标志,你没有使用适当的容器。 – Bathsheba

+4

@Bathsheba它看起来像适合我的容器。一般情况下,除非使用'std :: vector'(非关联容器),否则很少有情况。 –

+0

您没有提供任何细节,因此没有单一答案。名义上,如果您希望一次删除单个元素,那么使用remove-erase idiom可能会更有效,这在大多数实现中基本上都是做同样的事情。但是,由于它通过对向量进行分区来工作(将每个匹配与第一个分区的后面交换),它可能会执行大规模连续删除,具体取决于实现和用法。 – kfsone

回答

1

“我认为这取决于重复元素的数量吗?”

没有。 int没有析构函数,所以1个重复或1000个没有区别。任何一个功能需要做的都是设置正在使用的元素的新结束的内部记录。因此,remove()的性能在这里是高成本的事情,而不是resize/erase。 (即使有析构函数,它们也会循环调用它的相同数量的元素,几乎完全相同)。

几乎总是可以信任任何经验丰富的标准库实现,而不是做一些愚蠢的事情,所需时间远远超过必要的时间,所以考虑到行为是相同的 - 每个Jrok的答案 - 除非你的剖析器告诉你,否则没有理由进一步调查你去。

  • ,他们这样做,而不是更新一些“大小”成员不是由标准规定,但因为它支持iter != v.end()那里每次迭代器其实我已经看了商店实现“结束”的指针,这是有道理的被实现为指针而不慢开始+大小算术计算为end(),也同样难看特殊壳体所以递增的端-1迭代器产生一些定点状态。
3

重复次数相等,它们具有相同的复杂度。当缩小矢量,resize在术语的定义的erase

n3337,23.3.6.3表示:

void resize(size_type sz);

9效果:如果sz <= size(),相当于erase(begin() + sz, end());。 [...]

1

分析器说什么?这可以明显不同,从一个 实施到另一个(尽管只有一个常数 因子—复杂性需要是相同的)。

对于这个问题:有分析器显示你失去了太多 时间?写这个的惯用方法是:

a.erase(std::remove(a.begin(), a.end(), 8), a.end()); 

除非探查清楚地说,这是一个瓶颈,你 应该把它写在惯用的方式,让C++程序员 承认立刻发生了什么事,和唐”浪费时间 认识到你正在做同样的事情,并想知道为什么 你没有以惯用的方式做到这一点。