C/C++程序員對STL 容器肯定不會陌生, 以下是對常用容器進行 erase 操作注意事項的總結:
vector
vector 容器是用數組實現的, 它在內存是連續分佈的.對它進行 insert 或 erase 操作涉及到對插入點或刪除點後的元素進行移位, 所以插入點或刪除點後的iterator 會失效.
iterator erase( iterator pos );
iterator erase( const_iterator pos );
查看 STL 幫助得知vector::erase 函數的返回值是當前迭代器指針的下一個迭代器.
Iterator following the last removed element. If the iterator pos
refers to the last element, the end() iterator is returned.
所以對 vector 進行 erase 操作可以採用如下形式:
//刪除 vector1中值等於 num 的元素
for(; it != vector1.end(); ) {
if(num == *it)
it = vector1.erase(it);
else
++it;
}
list
STL 的list容器是採用雙向鏈表實現的, 使用不連續的內存空間存儲元素.inser時不會導致任何迭代器失效, erase 時刪除點的迭代器失效, 但是不影響其他迭代器. 它的 erase 函數類似 vector, 該函數返回值是當前迭代器指針的下一個迭代器.但是由於底層實現不同, list 的刪除操作可以採用更加靈活地方式.
//刪除 list1中值等於 num 的元素
for(; it != list1.end(); ) {
if(num == *it)
it = list1.erase(it);
//list1.erase(it++); //also OK
else
++it;
}
map
STL的 map 容器底層採用紅黑樹實現, 也就是說是一種平衡二叉樹, 它的插入和刪除效果和 list 類似.inser時不會導致任何迭代器失效, erase 時只有刪除點的迭代器失效, 其他迭代器不受影響. 代碼寫法也與 list 類似:
// 刪除 map1中所有 key 爲奇數的元素
for(auto it = map1.begin(); it != map1.end(); ) {
if(it->first % 2 == 1)
//it = map1.erase(it);
map1.erase(it++);
else
++it;
}
其他容器如 dequeue的操作方法借鑑vector, set 可以借鑑 map 這裏就不再贅述.一下是測試代碼:
//To complie: g++ -o test test.cpp -std=c++11
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <map>
using std::cout;
void test1()
{
std::vector<int> vi{1,2,3,3,3,5};
int num = 3;
std::vector<int>::iterator it = vi.begin();
//erase element whose value is 3
for(; it != vi.end(); ) {
if(num == *it)
it = vi.erase(it);
else
++it;
}
std::copy(vi.begin(), vi.end(), std::ostream_iterator<int>(cout, "\t"));
cout << '\n';
}
void test2()
{
std::list<int> li{1,2,3,3,3,5};
int num = 3;
std::list<int>::iterator it = li.begin();
//erase element whose value is 3
for(; it != li.end(); ) {
if(num == *it)
//it = li.erase(it);
li.erase(it++);
else
++it;
}
std::copy(li.begin(), li.end(), std::ostream_iterator<int>(cout, "\t"));
cout << '\n';
}
void test3()
{
std::map<int, std::string> map1 = {{1, "one"}, {2, "two"}, {3, "three"},
{4, "four"}, {5, "five"}, {6, "six"}};
// erase all odd numbers from map1
for(auto it = map1.begin(); it != map1.end(); ) {
if(it->first % 2 == 1)
//it = map1.erase(it);
map1.erase(it++);
else
++it;
}
for(auto& p : map1) {
cout << p.second << ' ';
}
cout << '\n';
}
int main() {
// test1();
// test2();
test3();
return 0;
}