4

我正在试验 tr1::unordered_map 并偶然发现了如何有效删除元素的问题。'erase' 方法提供通过键或迭代器删除。我认为后者效率更高,因为前者可能涉及隐式查找操作。另一方面,我在互联网上的调查显示,在调用 insert() 方法后,迭代器可能会变得无效。

我对典型的现实世界情况感兴趣,其中放入哈希表的对象具有足够长的生命周期,以便在该生命周期内调用 insert()。因此,我可以得出结论,在这种情况下,按键删除是唯一的选择吗?有没有其他方法可以更有效地删除对象?我完全意识到这个问题只在应用程序中很重要,因为删除经常发生。这是否会是我当前项目的情况,还有待观察,但我宁愿在设计我的项目时了解这些问题,而不是在已经存在大量代码时。

4

3 回答 3

5

无序容器的全部意义在于具有尽可能快的查找时间。担心按键擦除元素所花费的时间听起来像是过早优化的经典示例。

于 2011-09-19T16:30:19.453 回答
2

如果这对您很重要,因为您出于其他原因保留迭代器,那么 C++0xstd::unordered_map在 23.2.5/11 中提到(引用自 FDIS):

如果 (N+n) < z * B,insert 和 emplace 成员不应影响迭代器的有效性,其中 N 是插入操作之前容器中的元素数,n 是插入的元素数,B 是容器的桶数,z 是容器的最大负载因子。

我没有检查tr1规范是否具有相同的保证,但基于预期的实现它是相当合乎逻辑的。

如果您可以使用此保证,那么您可以在一定程度上保护您的迭代器。不过,正如马克所说,查找unordered_map应该很快。在 a 中保留键而不是迭代器比在 a 中保留索引而不是迭代器更糟糕vector,但比 for 中的等价物要好map

于 2011-09-19T17:50:33.093 回答
1

是的,insert()可以使所有迭代器无效。因此,我认为没有办法避免(隐式)查找。好消息是后者可能很便宜。

于 2011-09-19T16:26:36.253 回答