当我不关心顺序并且没有重复项时,更快的擦除删除成语?
faster erase-remove idiom when I don't care about order and don't have duplicates?
我有一个对象向量,想按值删除。 但是,该值仅出现一次,我不关心排序。
显然,如果这种按值删除非常普遍,和/或数据集非常大,那么向量就不是最好的数据结构。 但是,假设我已经确定情况并非如此。
需要明确的是,如果我的代码是 C,我会对以下内容感到满意:
void delete_by_value( int* const piArray, int& n, int iValue ) {
for ( int i = 0; i < n; i++ ) {
if ( piArray[ i ] == iValue ) {
piArray[ i ] = piArray[ --n ];
return;
}
}
}
似乎使用 std::algos 和容器方法的"现代习语"方法是:
v.erase(std::remove(v.begin(), v.end(), iValue), v.end());
但这应该慢得多,因为对于随机存在的元素,它是 n/2 移动和 n 比较。 我的版本是 1 个移动和 n/2 比较。
当然,在"现代成语"中,有比擦除-删除-成语更好的方法吗? 如果不是,为什么不呢?
使用std::find
替换循环。从end
迭代器的前置函数中获取替换值,并使用该迭代器erase
该元素。由于此迭代器是最后一个元素,因此erase
很便宜。奖励:bool
成功检查和template
int
的回报。
template<typename T>
bool delete_by_value(std::vector<T> &v, T const &del) {
auto final = v.end();
auto found = std::find(v.begin(), final, del);
if(found == final) return false;
*found = *--final;
v.erase(final);
return true;
}
当然,在
"现代成语"中,有比擦除-删除-成语更好的方法吗?
标准库中的每个利基用例都没有现成的功能。不稳定删除是未提供的功能之一。不过,不久前有人提出了(p0041r0(。同样,对于不包含重复项的向量的特殊情况,也没有特殊版本的算法。
因此,如果您希望使用最佳算法,则需要自己实现算法。线性搜索std::find
。之后,您只需要从最后一个元素分配并最终将其弹出即可。
如果使向量的大小变小,大多数std::vector::resize
实现都不会重新分配。因此,以下内容可能具有与 C 示例类似的性能。
void find_and_delete(std::vector<int>& v, int value) {
auto it = std::find(v.begin(), v.end(), value);
if (it != v.end()) {
*it = v.back();
v.resize(v.size() - 1);
}
}
C++方式与std::vector
基本相同:
template <typename T>
void delete_by_value(std::vector<T>& v, const T& value) {
auto it = std::find(v.begin(), v.end(), value);
if (it != v.end()) {
*it = std::move(v.back());
v.pop_back();
}
}
相关文章:
- 引用一个已擦除类型(void*)的指针
- 擦除while循环中迭代的元素
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- C++擦除(如果存在)
- 在映射擦除c++期间执行循环的次数
- 为什么擦除方法会影响结束方法
- C++ 字符串类擦除成员函数的时空复杂性
- 类型擦除的std::function与虚拟函数调用的开销
- C++14 中unordered_map矢量和擦除删除成语的奇怪行为
- C++ 擦除函数中需要澄清
- 循环挂起迭代的 std::擦除 on std::list
- 擦除许多矢量元素,同时使用'auto'
- 如何擦除冗余输入?
- C++ STL 设置按值擦除
- 当我不关心顺序并且没有重复项时,更快的擦除删除成语?
- 擦除删除成语的性能增益从何而来
- 为什么擦除-删除成语不适用于反向迭代器
- 擦除remove_if成语 - 删除了什么吗?
- 有没有办法将擦除-删除成语与其他循环条件一起使用
- 擦除增量成语失败,'vector iterator not compatible'