vector、map容器删除操作总结

来源:互联网 发布:战舰世界mac版 编辑:程序博客网 时间:2024/06/13 07:34


http://blog.csdn.net/shellching/article/details/4777496


1、关于vector中元素的删除和迭代器失效问题

[cpp] view plaincopy
  1. vector<int> vv;  
  2. vv.push_back(1);                                //加入第一个元素  
  3. vector<int>::iterator itBegin = vv.begin();   //获取第一个元素迭代器*itBegin=1  
  4. vv.push_back(2);                                //因为预留不够,所以发生内存搬移,之前迭代器将全部失效  
  5. vv.push_back(1);                                //即是说itBegin现在已经是个无效迭代器  
  6. vv.push_back(1);                                //所以使用vector迭代器一定要小心失效!  
  7. vv.push_back(3);                                //移动、增加、插入、删除以及reserve、resize都可能使迭代器无效!  
  8. vv.push_back(4);  
  9. vv.push_back(3);  
  10. vv.push_back(5);  
  11. vv.push_back(6);  
  12. int n = vv.size();      //n = 9  
  13.   
  14. vector<int>::iterator itrmv = remove(vv.begin(), vv.end(), 3);    //结果:1,2,1,1,4,5,6,5,6  
  15. n = vv.size();          //n = 9  
  16.   
  17. //删除vector中等于某值的所有元素  
  18. //remove算法只是对容器中有效元素向前移动覆盖无效元素,返回第一个无效元素指针  
  19. //1、它不会有删除动作 2、尾部无效元素没有意义 3、之后容器size不变  
  20.   
  21. vv.erase(itrmv, vv.end());          //结果:1,2,1,1,4,5,6  
  22. n = vv.size();                      //n = 7  
  23.   
  24. bool BeDelete(int n)  
  25. {  
  26.     return n == 1 || n == 2;  
  27. }  
  28.   
  29. //借助remove_if算法删除vecotr中符合某些条件的所有元素  
  30.   
  31. vv.erase(remove_if(vv.begin(), vv.end(), BeDelete), vv.end());  //结果:4,5,6  
  32. n = vv.size();      //n = 3  
  33.   
  34. //若用循环实现删除,需要注意erase后迭代器失效问题  
  35. for(vector<int>::iterator it=vv.begin(); it!=vv.end(); )  
  36. {  
  37.     if(*it == 4)  
  38.     {  
  39.         /*错误的做法 
  40.             vv.erase(it);   //对vector进行增加删除等操作后之前it可能无效 
  41.             it++;           //it此时已经无效 
  42.         */  
  43.         /*错误的做法 
  44.             vv.erase(it++); //erase后元素发生了移动所以it多向后跳过一个元素 
  45.         */  
  46.         it = vv.erase(it);  //正确的做法,erase返回下一个有效it  
  47.     }  
  48.     else  
  49.     {  
  50.         it++;  
  51.     }  
  52. }  
  53.   
  54. n = vv.size();              //n=2,结果:5,6  
  

 

2、释放vector容器多余的内存

[cpp] view plaincopy
  1. vector<int> vn;  
  2. vn.reserve(10);             //预留10个元素空间  
  3. int nn = vn.capacity();     //nn = 10  
  4.   
  5. vn.push_back(1);  
  6. vn.push_back(2);  
  7. nn = vn.capacity();         //nn = 10  
  8.   
  9. vector<int>(vn).swap(vn); //通过建立一个新对象释放多余空间  
  10. nn = vn.capacity();         //nn = 2  
  11. nn = vn.size();             //nn = 2  
  12.   
  13. vector<int>().swap(vn);   //会完全清空容器,释放所有空间  

 

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

 

[cpp] view plaincopy
  1. map<intint> mm;  
  2. mm.insert(make_pair(1,1));  
  3. mm.insert(make_pair(2,2));  
  4. mm.insert(make_pair(3,1));  
  5. mm.insert(make_pair(4,3));  
  6. mm.insert(make_pair(5,3));  
  7. mm.insert(make_pair(6,6));  
  8.   
  9. //注意:对map和set等自动排序的容器不应使用remove一类算法  
  10. //应使用for+erase或者while+find_if+erase  
  11.   
  12.   
  13. //第一种方法for+erase  
  14. map<intint>::iterator mit;  
  15.   
  16. for(mit = mm.begin(); mit != mm.end();)  
  17. {  
  18.     if(mit->second == 1)  
  19.     {  
  20.         mm.erase(mit++);    //这里需要注意  
  21.     }  
  22.     else  
  23.     {  
  24.         mit++;  
  25.     }  
  26. }                     
  27.   
  28. //第二种方法,while+find_if+erase  
  29.   
  30. //仅以元素做条件检索  
  31. bool mBeDelete(const pair<intint>& val)  
  32. {  
  33.     return val.second == 1;  
  34. }  
  35.   
  36. mit = find_if(mm.begin(), mm.end(), mBeDelete);  
  37. while(mit != mm.end())  
  38. {  
  39.     mit = find_if(mm.erase(mit), mm.end(), mBeDelete);  
  40. }  
  41.   
  42. //除元素外还需要传入另外一个条件参数  
  43.   
  44. //这里的参数无法使用常量引用  
  45. bool mBeDelete2(pair<intint> val, int n)  
  46. {  
  47.     return val.second == n;  
  48. }  
  49.   
  50. mit = find_if(mm.begin(), mm.end(), bind2nd(ptr_fun(mBeDelete2),3));  
  51. while(mit != mm.end())  
  52. {  
  53.     mit = find_if(mm.erase(mit), mm.end(), bind2nd(ptr_fun(mBeDelete2),3));  
  54. }  


原创粉丝点击