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())
怎么样?你的实际问题是什么?对于整数的向量,这无关紧要。