C++ 从C+中的向量末尾删除元素+;使用迭代器
我想从最后一个元素开始,以相反的顺序删除向量中的元素。据我所知,使用迭代器执行此操作的最简单方法是:C++ 从C+中的向量末尾删除元素+;使用迭代器,c++,vector,iterator,time-complexity,invalidation,C++,Vector,Iterator,Time Complexity,Invalidation,我想从最后一个元素开始,以相反的顺序删除向量中的元素。据我所知,使用迭代器执行此操作的最简单方法是: std::vector<int> data = ... std::vector<int>::iterator iter; for(iter = data.end() - 1; iter != data.begin() - 1; iter--) { data.erase(iter); } std::vector data=。。。 std::vector::iter
std::vector<int> data = ...
std::vector<int>::iterator iter;
for(iter = data.end() - 1; iter != data.begin() - 1; iter--) {
data.erase(iter);
}
std::vector data=。。。
std::vector::iter;
对于(iter=data.end()-1;iter!=data.begin()-1;iter--){
数据擦除(iter);
}
我的问题是,这些erase()调用中的每一个都是O(1),因为我们在最后删除,即使删除的一般复杂性是O(n)?另外,假设向量至少有一个元素,那么这个代码是否“安全”?有点像。std::vector erase()的复杂性是 删除(销毁)的元素数加上最后一个元素删除(移动)后的元素数为线性 根据这一来源: 由于您只删除了一个元素和最后一个元素,它与N=1呈线性关系,可以解释为O(1)常量。除非您确实需要按相反顺序删除它们,否则最好只调用
data.clear()
否则,不,这是不“安全的”:在调用后,形成数据.begin()-1
是未定义的,对其进行递减iter
。擦除也未定义 不,您的算法有UB。
如果没有,它将具有O(n)。
将主体更改为此将删除UB:iter=data.erase(iter)代码>
为什么?因为vector.erase()
的行为如下:
- 效果:在擦除点或之后使迭代器和引用无效李>
- 复杂性:T的析构函数被称为元素数的次数
已擦除,但T的移动赋值运算符的调用次数等于
删除元素后向量中的元素
如果像这样重写循环,它甚至可以用于空容器:
for(auto it = data.end(); it!=data.begin(); it = data.erase(it-1)) /**/;
它等于:
std::remove_if(data.rbegin(), data.rend(), [](data::reference x){return true;});
无论如何,使用data.clear()
、data.resize(0)
或使用临时空向量交换很可能更快。如果我想在迭代过程中根据条件“跳过”某些元素,该怎么办?我意识到这将不再是一个O(n)算法,但我可以简单地使用if(condition)it=data.erase(it-1);否则它--
并保持迭代器位置的一致性?是的,尽管这使您的算法是二次的:O(n²)
。最好使用反向迭代器调用std::remove_if()
。这是保证的O(n)
。谢谢!remove_if看起来是一种更干净的方法来完成我想做的事情——但是有没有一种方法可以检索remove_if删除的项目以供参考?您可以对谓词中的当前元素执行任何操作。甚至把它复制到其他地方保存。@Donny不,它们被覆盖了。你真的想分割向量吗?data.erase(data.rbegin(),data.rend())
怎么样?你的实际问题是什么?对于整数的向量,这无关紧要。