for循环中调用vector容器erase函数
代码示例
- int main(){
- vector<int> a;
- a.push_back(3);
- a.push_back(2);
- a.push_back(3);
- a.push_back(3);
- a.push_back(5);
- vector<int>::iterator b;
- int x = 3;
- for(b=a.begin();b!=a.end();b++)
- {
- if(*b==x){
- b=a.erase(b);
- }
- }
- for(b=a.begin();b!=a.end();b++)
- {
- printf("value=%d\n", *b);
- }
- return 0;
- }
现象&后果
上面代码的目的是,使用迭代器循环删除vector中所有的3,但你会发现并不是所有的3都被删除掉了。
Bug分析
上述代码主要问题是对容器类vector的erase函数理解不够。代码中调用的erase函数在删除当前元素b后,返回b后面的元素。在上述代码的vector中,一开始有3个3,其中后两个3是连续的,在删除第二个3之后,erase函数返回的下一个元素还是3,然而代码运行到循环的b++时,就略过了这个3,从而造成不是所有的3都被删除。
正确的做法是,在删除元素的之后,由于erase函数已经自动跳到下一个元素,跳过接下来循环的b++语句。
正确代码
- int main(){
- vector<int> a;
- a.push_back(3);
- a.push_back(2);
- a.push_back(3);
- a.push_back(3);
- a.push_back(5);
- vector<int>::iterator b;
- int x = 3;
- for(b=a.begin();b!=a.end();)
- {
- if(*b==x){
- b=a.erase(b);
- }else{
- b++;
- }
- }
- for(b=a.begin();b!=a.end();b++)
- {
- printf("value=%d\n", *b);
- }
- return 0;
- }
编程建议
在对容器类元素进行增、删操作时,一定要注意增、删操作的返回值和迭代器指示器是否发生变化,必要的时候需要进行修正。
from:http://book.51cto.com/art/201311/419438.htm
相关推荐
c++之vector容器erase操作,在容器列表中删除中间一行的操作过程,代码分为一维容器和二维容器操作两部分,详细见代码
vector循环删除的时候,erase...vector和map都不能将it++写在for循环中,而在循环体内erase(it)! 代码如下:void main(){ vector<int> v; v.push_back(1); v.push_back(2); v.push_back(4); v.push_back(3); v.pus
erase的用法删除vector中特定的元素。非常简单实用。
在使用 list、set 或 map遍历删除某些元素时可以这样使用,如下所示
##CIRCULAR_VECTOR## 用 C++ 编写的符合 STL 的圆形向量(容器)数据结构与循环缓冲区数据结构有相似之处,除了允许访问容器中的所有元素。 包含与来自 STL 的 C++98 std::vector 相同的所有成员函数,但 vector::...
自己编写的类vector类,可以实现vector的大部分功能。 该类包含的功能有: 初始化: 默认初始化 拷贝初始化 列表初始化 使用数目和值进行初始化 赋值 操作: size 返回元素数目 capatity 返回容器暂时可...
条款43: 尽量用算法调用代替手写循环 条款44: 尽量用成员函数代替同名的算法 条款45: 注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别 条款46: 考虑用函数对象代替函数作为算法的...
C++string中的assign()、erase()、swap()函数 代码实在,如下: #include using namespace std; int main() { string str=hello; cout<<str.erase(1)<<endl;//没有第二个参数,默认删除原串下标为1的...
本篇文章是对C++ list中erase与remove函数的使用进行了详细的分析介绍,需要的朋友参考下
C++ vector中实际删除元素使用的是容器vecrot std::vector::erase()方法。C++ 中std::remove()并不删除元素,因为容器的size()没有变化,只是元素的替换。 1.std::vector::erase() 函数原型:iterator erase ...
条款43: 尽量用算法调用代替手写循环 条款44: 尽量用成员函数代替同名的算法 条款45: 注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别 条款46: 考虑用函数对象代替函数作为算法的...
代码如下:#include <iostream>#include <vector>#include <list>#include <iterator>using namespace std; void Remove1(vector<int> &vec, int num){ vector<int>::iterator iter; for (iter=vec.begin(); iter!=...
条款43:尽量用算法调用代替手写循环 条款44:尽量用成员函数代替同名的算法 条款45:注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别 条款46:考虑使用函数对象代替函数作算法的...
项目任务在单链表类中增加一个功能erase(x y) 删除表中所有值在 [x y] 之间的结点。假设链表中结点数值类型是整形,要求编程返回删除相应结点后的链表长度和链表元素。输入描述第一行输入链表List的结点元素值,元素...
1.连续内存序列容器(vector,string,deque) 序列容器的erase方法返回值是指向紧接在被删除元素之后的元素的有效迭代器,可以根据这个返回值来安全删除元素。 vector<int> c; for(vector<int>::iterator it = c.begin...
简易版vector,用模板类实现。实现函数有:capacity,reserve,push_back,pop_back,size,swap,empty,clear,erase。
fun、mem_fun和mem_fun_ref的原因 条款42:确定less表示operator使用STL编程 条款43:尽量用算法调用代替手写循环 条款44:尽量用成员函数代替同名的算法 条款45:注意count、find、binary_search、...
废话不多说,先看下面一段代码 #include #include using namespace std; class A { public: typedef std::map<int> myMap;...void mapInsert(int i, string s) ...map.insert(std::make_pair(i, s)...map.erase(it->first)
程序说明: 说明 运行可执行程序CAR.exe...本题用到了10H、21H函数库的函数调用。 10H号函数库:CS=410h+2h=42h , IP=410h=40h 。中断向量为0:40H。 21H号函数库:CS=421h+2h=86h , IP=421h=84h 。中断向量为0:84h。