我是靠谱客的博主 健康毛巾,这篇文章主要介绍vector/list/map/set的插入、删除、遍历 - remove\erase函数,现在分享给大家,希望可以做个参考。

1、vector中删除满足某些条件的元素和迭代器失效问题

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream> #include <vector> using namespace std; int main() { std::vector<int> mVector; mVector.push_back(1); //插入元素push_back mVector.push_back(2); mVector.push_back(0); mVector.push_back(3); mVector.push_back(4); mVector.push_back(0); mVector.push_back(0); mVector.push_back(6); mVector.push_back(0); mVector.push_back(0); std::vector<int>::iterator iter = mVector.begin(); for (; iter != mVector.end(); ) //删除操作 { if (0 != *iter) { ++iter; } else { iter = mVector.erase(iter); //方式一(正确) //mVector.erase(iter++); //方式二(错误) //mVector.erase(it); it++; //方式三(错误) } for (iter = mVector.begin();; iter != mVector.end(); ++iter)//vector遍历操作 { std::cout << " " << *iter << " "; } return 0; }
复制代码
1
2
3
4
5
6
【错误分析】 /*方式三:错误 vv.erase(it); //对vector进行增加删除等操作后之前it可能无效 it++; //删除后it此时已经无效,it成为野指针,不能执行it++操作 /*方式二:错误 该种情况,vector、deque不能用,但是list、map、set可以!

2、list中删除满足某些条件的元素

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream> #include <list> using namespace std; int main() { std::list<int> mList; mList.push_back(1); //插入操作push_back mList.push_back(2); mList.push_back(0); mList.push_back(3); mList.push_back(4); mList.push_back(0); mList.push_back(0); mList.push_back(6); mList.push_back(0); mList.push_back(0); std::list<int>::iterator iter = mList.begin(); for (; iter != mList.end(); ) //删除操作 { if (0 != *iter) { ++iter; } else { iter = mList.erase(iter); //方式一(正确) //mList.erase(iter++); //方式二(正确) //mList.erase(iter); iter++; //方式三(错误) } } iter = mList.begin(); for (; iter != mList.end(); ++iter) //遍历操作 { std::cout << " " << *iter << " "; } return 0; }

3、map中删除满足某些条件的元素
注意:对map和set等自动排序的容器不应使用remove一类算法

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream> #include <string> #include <map> using namespace std; int main(int argc, char* argv[]) { map<int, string> mapData; //插入元素方式(四种) mapData.insert(pair<int,string>(0,"aaa")); mapData[1] = "bbb"; mapData.insert(make_pair<int,string>(2,"ccc")); mapData.insert(map<int,string>::value_type(3,"ddd")); for (map<int, string>::iterator it=mapData.begin(); it!=mapData.end(); /*it++*/) //删除操作 { if ((*it).first == 2) { it = mapData.erase(it); //方式一(正确) //mapData.erase(it++); //方式二(正确) //mVector.erase(it); it++; //方式三(错误) } else { it++; } } for (map<int, string>::iterator it=mapData.begin(); it!=mapData.end(); it++) //map遍历输出 { cout<<(*it).first<<" "<<(*it).second<<endl; //取值操作方式 (*it).first和(*it).second } return 0; }

3、set中删除满足某些条件的元素

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<iostream> #include<set> using namespace std; int main() { set<int> s; s.insert(5); //第一次插入5,可以插入 s.insert(1); s.insert(0); s.insert(3); s.insert(5); //第二次插入5,重复元素,不会插入 s.erase(-1); set<int>::iterator it = s.begin(); for(;it != s.end();) //删除操作 { if(*it < 2) { //it = s.erase(it); //方式一(正确) //s.erase(it++); //方式二(正确) //s.erase(it); it++; //方式三(错误) } else it++; } for(it = s.begin(); it != s.end(); it++) //遍历操作 cout << *it << " "; return 0; }

综上所述,
对于删除操作:
方式一都正确;
方式三都错误;
方式二vector/deque等顺序容器错误、list/map/set等关联容器正确。

>

【重点:remove和erase讲解】
1、 erase一般作为一个container的成员函数,是真正删除的元素,是物理上的删除。
2、作为算法项目组的remove类函数,是逻辑上的删除,将被删除的元素移动到容器末尾,然后返回新的末尾,此时容器的size不变更。
3、项目组容器若有成员函数remove,那么代表的是真正物理意义上的删除元素。
4、若是该容器是vector、string或者deque,应用erase-remove idiom或者erase-remove_if idiom。
5、若是该容器是list,应用list::remove或者list:remove_if成员函数。
6、 若是该容器是一个联合 container,应用asso_con::erase成员函数或者remove_copy_if连络swap等体式格式。
7、有一些斗劲特别的容器具现,比如vector等,暂不推敲。

【remove和erase对比】 一般情况下,remove是STL的函数,#include < algorithm >,而erase是容器的成员函数,#include <容器> 。 使用remove不能真正的删除元素!
如果你真的要删除东西的话,可以用下面两种形式:erase-remove、erase。

复制代码
1
2
3
4
5
6
7
vector<int> v; v.erase(remove(v.begin(), v.end(), 99), v.end());//删除容器v中的所有的值为99的元素 //[总结] //使用的固定形式: //v.erase(remove(v.begin(), v.end(), VALUE), v.end()); //这句的意思是,取得VALUE的位置(位于结尾),然后删除VALUE到原vector结尾的所有元素
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
// remove all elements from Numbers that match 10 vector<int>::iterator ret = remove(Numbers.begin(), Numbers.end(), 10) ; 【解释】原vector { 10 20 10 15 12 7 9 },删除10,会将10后面的元素移动到前面 (注意以下逐个元素对齐,模拟元素在内存中的位置,这样就容易看出变化规律) 原vector 10 20 10 15 12 7 9 遇到第一个10,数组变成 20 10 15 12 7 9 遇到第二个10移动到7 9之后又遇到第三个10于是剩下内存中未移动的7 9 20 15 12 7 9 7 9 遇到第三个10 20 15 12 7 9 7 9

但是,有特例— — list容器**
对于list,因为list有成员函数remove,因此调用list的remove成员函数可以“真的”删除,且比应用erase-remove惯用法更高效!

复制代码
1
2
3
4
5
list<int> li; // 建立一个list // 放一些值进去 li.remove(99); // 除去所有等于99的元素 // 真的删除值为99的元素 // 所以list的大小可能改变了

最后

以上就是健康毛巾最近收集整理的关于vector/list/map/set的插入、删除、遍历 - remove\erase函数的全部内容,更多相关vector/list/map/set的插入、删除、遍历内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(67)

评论列表共有 0 条评论

立即
投稿
返回
顶部