C++ std::remove和vector::erase用于向量的区别
std::remove: 它实际上不会从容器中删除元素,只会将未删除的元素向前移动到已删除元素的上方。
vector::erase: 从向量中删除单个元素(位置)或一系列元素([first,last)
)。
std::remove vs vector::erase
- 使用erase,向量中的所有元素都将向后移动1,从而导致大量复制; std :: remove只进行“逻辑”删除,并通过移动处理来保留向量不变。
- 如果需要从向量中删除多个元素,则std :: remove将每个未删除的元素仅复制一次到其最终位置,而vector :: erase方法将多次移动从位置到末尾的所有元素。
- 例如,请考虑从以下向量中删除所有元素<5。
std::vector v { 1, 2, 3, 4, 5 };
// remove all elements < 5
- 使用erase,如果你逐个去除元素,则将去除1,从而导致移动的剩余元素(4)的副本。然后你会移除2,并将所有剩余元素向前移动一个(3)……如果你看到 这个模式是O(N ^ 2)算法。在std :: remove的情况下,算法维护一个头部,并迭代容器。对于前4个元素,头将被移动并测试元素,但不会复制元素。仅针对第五个元素,该对象将从最后位置复制到第一位置,并且该算法将通过单次复制完成并返回指向第二位置的迭代器。这是O(N)算法。后一个 使用vector :: erase和范围会导致全部剩余元素的销毁并调整容器大小。
- 因此,erase()是您可以对容器中的元素执行的操作,删除()是您可以对范围执行的操作,因为它重新排列该范围,但不会从范围中删除任何东西。
// CPP program to illustrate
// difference b/w std::remove
// and std::vector::erase algorithm
#include <bits/stdc++.h>
int main()
{
std::vector<int> vec{ 10, 20, 30, 30, 20, 10, 10, 20 };
std::vector<int> ve{ 10, 20, 30, 30, 20, 10, 10, 20 };
// Print original vector
std::cout << "Original vector :";
for (int i = 0; i < vec.size(); i++)
std::cout << " " << vec[i];
std::cout << "\n";
// Iterator that store the position of last element
std::vector<int>::iterator pend;
// std :: remove function call
pend = std::remove(vec.begin(), vec.end(), 20);
// Print the vector after std :: remove
std::cout << "Range contains:";
for (std::vector<int>::iterator p = vec.begin(); p != pend; ++p)
std::cout << ' ' << *p; std::cout << '\n';
// Print original vector
std::cout << "Original Vector :";
for (int i = 0; i < ve.size(); i++)
std::cout << " " << ve[i];
std::cout << "\n";
// std :: vector :: erase function call
// erase the first 3 elements of vector
ve.erase(ve.begin(), ve.begin() + 3);
// Print the vector
std::cout << "Vector contains :";
for (int i = 0; i < ve.size(); i++)
std::cout << " " << ve[i];
std::cout << "\n";
return 0;
}
Output:
原始向量: 10 20 30 30 20 10 10 20
范围包含: 10 30 30 10 10
原始向量: 10 20 30 30 20 10 10 20
向量包含: 30 20 10 10 20
让我们用表格形式来比较-:
ID | std::remove | vector::erase |
---|---|---|
1 | 它在头文件 |
它从向量中删除单个元素。 |
2 | 其语法为-:remove(const char* filename); | 其语法为-:iterator erase (const_iterator position); |
3 | 它需要一个参数,即文件名 | 它返回一个随机访问迭代器。 |
4 | 如果文件被成功删除,则返回0,否则返回非零值 | 它的时间复杂度是O(N) |