C++中vector::erase和std::remove的区别
std::remove:它实际上并不是从容器中删除元素,而是将未删除的元素转发到已删除元素之上。vector::erase:从vector中移除单个元素(位置)或一组元素([first, last)])。
std::remove 和 vector::erase 区别
- 通过使用erase操作,std::vector中的所有元素将被移动1,导致大量的拷贝;Std::remove只做一个“逻辑”删除,并通过移动对象来保持vector对象不变。
- 如果需要从vector中删除多个元素,标准::remove将每个未删除的元素只复制一次到最终位置,而vector::erase方法将将该位置的所有元素多次移动到末尾。
- 例如,考虑删除后面vector中所有< 5的元素。
std::vector v { 1, 2, 3, 4, 5 };
// remove all elements < 5
- 使用erase,如果你在vector中逐个删除元素,你会移除1,导致剩下的元素被平移(4)。然后你会移除2,并将所有剩下的元素都平移(3).如果你看到这个模式,这是一个O(N^2)算法。在std::remove的情况下,算法维护一个头,并在容器上迭代。对于前4个元素,头部将被移动,元素将被测试,但不会复制元素。只有第5个元素的对象才会从最后一个位置复制到第一个位置,算法会完成单个复制并返回到第二个位置的迭代器。这是一个O(N)算法。后面的std::vector::erase操作将导致销毁所有剩余元素并调整容器大小。
- 因此,erase()是可以对容器中的元素做的事情,remove()是可以对一个范围做的事情,因为它会重新安排范围,但不会从范围中擦除任何东西。
// 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;
}
输出:
Original vector : 10 20 30 30 20 10 10 20
Range contains: 10 30 30 10 10
Original Vector : 10 20 30 30 20 10 10 20
Vector contains : 30 20 10 10 20
让我们用表格的形式来看看它们的区别:
序号 | std::删除 | 向量:擦除 |
---|---|---|
1. | 它在头文件 |
它从vector中移除单个元素。 |
2. | 它的语法是-: remove(const char* filename); |
它的语法是-: iterator erase (const_iterator position); |
3. | 它接受一个参数作为文件名 | 它返回一个随机访问迭代器。 |
4. | 如果文件删除成功,则返回0,否则返回non – 0 | 其时间复杂度为O(N) |