如何在排序的向量上正确应用擦除-删除习惯用法
how can I correctly apply the erase remove idiom on a sorted vector?
通常,我们希望应用擦除-删除习惯用法来正确地从向量中删除元素,例如:
v.erase( std::remove( std::begin(v), std::end(v), 5 ), std::end(v) );
其中v是整数的向量。
但如果先对向量进行排序呢?下面的方法会做同样的事情吗?如果是,这是最理想的方法吗?
std::sort(v.begin(), v.end());
IntegerVector::iterator it = std::lower_bound(v.begin(), v.end(), 5);
if(it != v.end()) {
(void)v.erase(it, v.end());
}
这是否正确地应用了删除习语?向量在移除过程之后仍然排序吗(我假设是这样)?我们不需要这样做吗:
(void)v.erase(std::remove(it), v.end());
(std::remove的语法不正确,但希望您能理解)。
谢谢,
本。
您可以使用:
auto range = std::equal_range(std::begin(v), std::end(v), 5);
v.erase(range.first, range.second);
对于C++03,您必须将auto
替换为(详细的)std::pair<IntegerVector::iterator, IntegerVector::iterator>
std::equal_range
返回一对迭代器,其中范围[first, second)
的值等于给定值(此处为5
)(假设v
已排序)。
它不再是擦除-删除习惯用法,但是的,它将正确、最佳、稳定地完成任务。
std::remove
在擦除之前将所有不需要的元素收集到一个连续的块中,但您的排序已经完成了,因此不需要它。
您可以删除无意义的(void)
前缀。
假设您想要删除所有等于5的元素,那么您的代码肯定是不正确的。以下是更正后的版本:
std::sort(v.begin(), v.end());
auto lower = std::lower_bound(v.begin(), v.end(), 5);
if(lower != v.end()) {
auto upper = std::upper_bound(lower,v.end(), 5);
v.erase(lower,upper);
}
相关文章:
- 引用一个已擦除类型(void*)的指针
- 擦除while循环中迭代的元素
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- C++擦除(如果存在)
- 在映射擦除c++期间执行循环的次数
- 为什么擦除方法会影响结束方法
- C++ 字符串类擦除成员函数的时空复杂性
- 类型擦除的std::function与虚拟函数调用的开销
- C++14 中unordered_map矢量和擦除删除成语的奇怪行为
- C++ 擦除函数中需要澄清
- 循环挂起迭代的 std::擦除 on std::list
- 擦除许多矢量元素,同时使用'auto'
- 如何擦除冗余输入?
- C++ STL 设置按值擦除
- 如何在C++中允许成员函数的自定义返回类型进行类型擦除?
- 为什么我的向量::擦除调用会抛出"vector subscript out of range"?
- 如何在写入文件时擦除最后一个逗号
- C++:std::ofstream 方法 open() 在第二次迭代时擦除打开的 ifstream 文件
- 如何擦除提升中的所有元素:multi_index应用"deleter"
- 如何在排序的向量上正确应用擦除-删除习惯用法