对于容器vector、set
最近在看阿秀的八股文pdf时发现一条似乎有点问题,于是做了实验,以vector和set为例,这两个容器的erase函数都会返回下一个元素的迭代器,但是顺序容器vector确实不能使用erase(it++),此时it指向的并不是被删元素的下一个元素,具体可见下面的代码
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#include <vector>
#include <set>
void printSet(set<int>& s)
{
for (set<int>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
//插入和删除
void test02()
{
set<int> s1;
//插入
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(40);
printSet(s1);
//删除
auto k = s1.begin();
auto k1 = s1.erase(k++);
cout << *k << endl;
cout << *k1 << endl;
printSet(s1);
//清空
//s1.erase(s1.begin(), s1.end());
s1.clear();
printSet(s1);
}
void printVector(vector<int>& v) {
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
//插入和删除
void test01()
{
vector<int> v1;
//尾插
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
printVector(v1);
//删除
auto k = v1.begin();
auto k1=v1.erase(k++);
cout << *k << endl;
cout << *k1 << endl;
printVector(v1);
//清空
v1.erase(v1.begin(), v1.end());
v1.clear();
printVector(v1);
}
int main() {
cout << endl;
cout << "----------------Vector--------------" << endl;
test01();
cout << "----------------Set--------------" << endl;
test02();
system("pause");
return 0;
}
输出结果如下:
第三行输出的时erase容器的返回迭代器所指向的元素,可以发现都是20,这个都没问题,但是vector的k却指向错误
----------------Vector--------------
10 20 30 40
30
20
20 30 40
----------------Set--------------
10 20 30 40
20
20
20 30 40
本来以为失效后,这个迭代器应该指向一个未知数,结果指向的是30,后来又做了新的实验,把test01改为下面的代码:
k指向30,利用erase删除30这个值
void test01()
{
vector<int> v1;
//尾插
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
printVector(v1);
//删除
auto k = v1.begin();
k++;
auto k1=v1.erase(k++);
cout << *k << endl;
cout << *k1 << endl;
printVector(v1);
//清空
v1.erase(v1.begin(), v1.end());
v1.clear();
printVector(v1);
}
结果如下
----------------Vector--------------
10 20 30 40
40
30
10 30 40
----------------Set--------------
10 20 30 40
20
20
20 30 40
发现使用erase后k总会指向被删除元素的后面的后面的位置,此时指向的都是合法的位置,继续更改代码,将k指向30,再利用erase删除,test01代码如下:
void test01()
{
vector<int> v1;
//尾插
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
printVector(v1);
//删除
auto k = v1.begin();
k++;
k++;
cout << "before erase k=" << *k << endl;
auto k1=v1.erase(k++);
cout << "after erase k=" << *k << endl;
cout << *k1 << endl;
printVector(v1);
//清空
v1.erase(v1.begin(), v1.end());
v1.clear();
printVector(v1);
}
结果如下:
----------------Vector--------------
10 20 30 40
before erase k=30
after erase k=40
40
10 20 40
----------------Set--------------
10 20 30 40
20
20
20 30 40
很奇怪,为什么还是指向最后一个数,继续++,再做实验,此时test01代码更改如下:
void test01()
{
vector<int> v1;
//尾插
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
printVector(v1);
//删除
auto k = v1.begin();
k++;
k++;
k++;
cout << "before erase k=" << *k << endl;
auto k1=v1.erase(k++);
cout << "after erase k=" << *k << endl;
cout << *k1 << endl;
printVector(v1);
//清空
v1.erase(v1.begin(), v1.end());
v1.clear();
printVector(v1);
}
结果如下:
----------------Vector--------------
10 20 30 40
before erase k=40
after erase k=0
40
10 20 30
----------------Set--------------
10 20 30 40
20
20
20 30 40
总结:顺序容器使用erase之后后面的迭代器都会失效,所以在今后写代码时需要多注意下,而关联式容器只是被删除的元素的迭代器失效,后面的迭代器还是可以用的