【发布时间】:2011-05-06 03:25:31
【问题描述】:
我有一个std::vector<int> 和第二个容器,其中包含迭代器或索引(没有键,我希望不断访问该元素)到该向量以用于删除目的。
假设我有一个包含 1000 个元素的向量,并且想要删除其中的 200 个。在删除操作之后,未删除元素的顺序应该和之前一样。
在我的问题的第一个版本中我错过了另一件事:值是唯一的。它们是身份。
您将如何以安全(关于 stl 规则)和有效的方式(向量的决定应为最终决定)来做到这一点?
可能性或方法我想过:
- erase-remove idiom (http://en.wikipedia.org/wiki/Erase-remove_idiom):最初用于删除满足条件的元素(包括线性搜索),但我考虑大小为 1 的范围,此方法可用于已经给定的迭代器和虚拟条件。 问题:是否保留了元素的原始顺序,是否比上一种方法更高效?
- 遍历索引并使用
vector.erase(vector.begin()+index+offset)擦除元素,同时将删除的索引保留在容器中以计算偏移量。可以使用std::lower_boundn 已删除元素的容器为每次删除迭代确定此偏移量。 问题:由于随机位置删除,很多 binary_searches 用于获取偏移量和大量移动操作。 - 目前我正在执行以下操作:获取要删除的元素的所有迭代器。根据向量中的位置以降序对它们进行排序,并循环它们以使用
vector.erase进行最终删除。现在我没有使任何迭代器失效,并且除了删除本身之外没有向量重新排列操作。 问题:很多排序
那么,你将如何解决这个问题?有什么新想法吗?有什么建议吗?
感谢您的意见。
萨沙
编辑/更新/自己的结果:我实现了erase-remove idiom,这也是KennyTM提到的,谓词基于在一个 boost::dynamic_bitset 并且它非常快。此外,我尝试了 PigBen 的移动和截断方法(Steve Jessop 也提到过),它也在其 while 循环中访问位集。对于我的数据,两者似乎都同样快。我尝试删除 1000 个元素中的 100 个(无符号整数),这 100 个删除了 1M 次,没有显着差异。因为我认为基于 stl 的擦除删除习语有点“自然”,所以我选择了这种方法(KennyTM 也提到了这个论点)。
【问题讨论】:
-
有点吹毛求疵,但是当您在第一句话中说“没有键”时,您似乎在谈论价值观。数组(IMO)的“键”是索引。你在说什么。
标签: c++ algorithm stl performance std