STL基础5:vector容器的使用总结一.vector使用构造函数的四种初始化方式//1.默认构造函数,长度为0的空向量//vectorintv1;//2.带有单个整形参数的构造函数,长度为50的空向量//vectorintv2(50);//vectorintv3(50,1);//长度为50,初始值为1的向量//3.复制构造函数,构造一个新的向量v4,作为已存在的向量v2的完全复制//vectorintv4(v2);//4.带两个常量参数的构造函数,产生初始值为一个区间的向量。区间由一个左闭右开的半开区间[first,last)来指定//vectorintv5(first_Iter,end_Iter);假设有int数组:intv1[10]={0,1,0,0,3,0,0,4,4,4};第一种初始化方式:带有单个整形参数的构造函数[cpp]viewplaincopyprint?1.vectorintvecInit1(10);//和vectorintvecInit1;vecInit1.resize(10);一样2.for(inti=0;i10;i++)3.{4.vecInit1.push_back(v1[i]);//将数组v1的元素添加到向量init1的最后5.}//注意,push_back每执行一次会调用一次Vector的对象vecInit1的构造函数和析构函数,效率很低啊慎用这种容器动态添加元素第二种初始化方式:带两个迭代器参数的构造函数//左闭右开区间,左边从数组[0]的地址开始拷贝数组元素,到右边的数组[10]之前一个的地址结束//也就是说如果要拷贝数组v1里的10个元素,就必须在右边,数组最后一个元素的地址再加上1(&v1[9]+1)[cpp]viewplaincopyprint?1.vectorintvecInit2(&v1[0],&v1[9]+1);第三种初始化方式:默认构造函数[cpp]viewplaincopyprint?1.vectorintvecInit3;2.vecInit3.reserve(10);//预先设置vector的元素容纳数量,提前预留空间3.vecInit3.insert(vecInit3.begin(),&v1[0],&v1[9]+1);//后面两个参数同样也是左闭右开第四种初始化方式:复制构造函数[cpp]viewplaincopyprint?1.vectorintvecInt4(vecInit3);二.vector的三种遍历向量里元素的方式假设有一个数组:intv2[10]={0,1,0,0,3,0,0,4,4,4};vectorintvecForeach1(&v2[0],&v2[9]+1);第一种:.遍历向量vecForeach1的下标方式[cpp]viewplaincopyprint?1.for(inti=0;ivecForeach1.size();i++)2.{3.printf(遍历向量vecForeach1的下标方式取vecForeach1里的元素为%d\n,vecForeach1[i]);4.}第二种.使用迭代器遍历vecForeach1向量方式[cpp]viewplaincopyprint?1.for(vectorint::iteratoriter=vecForeach1.begin();itervecForeach1.end();iter++)2.{3.printf(使用迭代器遍历vecForeach1向量方式取vecForeach1里的元素为%d\n,*iter);4.}//可以优化上面的代码1.使用typedefvectorint::iteratorVector_Iter将vectorint::iterator另外定义一个名字为Vector_Iter//2.先计算vecForeach1.end()的值,不用在for里每次都去计算一次;//3.在for里使用iter的前置++,效率更高//4.写算法的时候尽量使用!=比较迭代器,因为对于很多非随机迭代器没有这个操作符//优化后代码为:[cpp]viewplaincopyprint?1.typedefvectorint::iteratorVector_Iter;2.Vector_IteriterEnd=vecForeach1.end();3.for(Vector_Iteriter=vecForeach1.begin();iter!=iterEnd;++iter)4.{5.printf(优化后的使用迭代器遍历vecForeach1向量方式取vecForeach1里的元素为%d\n,*iter);6.}第三种:.使用STL的算法类里的for_each,需要包含头文件#includealgorithm,首先需要定义一个Vector_ForeachCoutFun的方法将元素输出[cpp]viewplaincopyprint?1.voidVector_ForeachCoutFun(int&outIndex)2.{3.printf(使用foreach输出vecForeach1里的元素为%d\n,outIndex);4.}然后调用for_each将元素输出[cpp]viewplaincopyprint?1.for_each(vecForeach1.begin(),vecForeach1.end(),Vector_ForeachCoutFun);三.vector的删除操作1.可以使用四种方式删除vector中的元素:第一种是使用向量容器vector的成员函数erase(使用这种方式并不能清除删除元素所占的内存空间),由于向量容器vector中的元素在内存中都是按顺序排放的,所以删除某个元素后,会导致迭代器失效,所以或者(重新更新迭代器begin和end)或者(更新迭代器end和利用erase返回指向被删除元素的下一个元素的有效迭代器更新)这两种方式都可以使迭代器不失效;SAMPLES:[cpp]viewplaincopyprint?1.intv3[10]={0,1,2,3,4,5,6,7,8,9};2.vectorintvecDeleted1(&v3[0],&v3[9]+1);3.4.typedefvectorint::iteratorVector_Iter;5.Vector_IteriterEnd=vecDeleted1.end();6.for(Vector_Iteriter=vecDeleted1.begin();iter!=iterEnd;++iter)7.{8.vecDeleted1.erase(iter);//使用erase迭代器失效9.10.}上面的代码是要依次删除vecDeleted1里的所有元素,但是会有一个问题,当删除第一个元素0后,再次遍历的时候,迭代器会报错,这就是迭代器失效造成的,所以可以使用(更新迭代器end和利用erase返回指向被删除元素的下一个元素的有效迭代器更新)的方式更新迭代器,修改代码如下:[cpp]viewplaincopyprint?1.intv3[10]={0,1,2,3,4,5,6,7,8,9};2.vectorintvecDeleted1(&v3[0],&v3[9]+1);3.4.typedefvectorint::iteratorVector_Iter;5.//Vector_IteriterEnd=vecDeleted1.end();6.for(Vector_Iteriter=vecDeleted1.begin();iter!=vecDeleted1.end();++iter)7.{8.iter=vecDeleted1.erase(iter);//使用erase返回指向被删除元素的下一个元素的有效迭代器更新9.}将迭代器iter更新到删除元素的下一个元素,然后在for循环里使用vecDeleted1.end()代替原先的iterEnd,每次遍历的时候都更新一下vector的最末元素迭代器end()(要是不跟新这个,那么使用原先的end()指向了一个未知区域,程序当然报错)这样程序就不会报错使用erase删除特定元素3的方式:[cpp]viewplaincopyprint?1.Vector_IteriterVecDel=find(vecDeleted1.begin(),vecDeleted1.end(),3);2.if(iterVecDel!=vecDeleted1.end())3.{4.vecDeleted1.erase(iterVecDel);5.}首先使用STL算法类里的find方法,找到元素3,返回一个指向元素3的迭代器iterVecDel1,然后使用erase方法将元素3删除思考:如果使用erase删除了一个向量vector元素,那么其他元素在内存中是怎么移动的呢vecDeleted1:0,1,2,3,4,5,6,7,8,9vecDeleted1[9]==9删除元素3后:[cpp]viewplaincopyprint?1.Vector_IteriterVecDel=find(vecDeleted1.begin(),vecDeleted1.end(),3);2.if(iterVecDel!=vecDeleted1.end())3.{4.vecDeleted1.erase(iterVecDel);5.6.}vecDeleted1:0,1,2,4,5,6,7,8,9那么原先vecDeleted1[9]的位置元素是什么呢,那块内存还有元素吗,答案是肯定的,由于vector使用erase删除元素时,虽然将删除的元素从向量中移走了,然后移走后面的所有元素都是很有次序的往前移了一步,那么最后一块内存里的值原先是9,9向前移了一步,那么原先的那块内存vecDeleted1[9]还是9,并没有删除那块9这个元素,所以使用erase虽然从表面上看向量vector里的元素变少了,但是实际暂用的内存可没有变少哦!切记,既然erase不能把该死的元素从内存中移除,那不是很危险,该怎么办呢,所以下面的第二种方法就能彻底的解决这个问题。第二种是使用STL算法类里的remove函数和erase搭配的方式进行删除(此方式不用更新迭代器)(实际上在vector容器使用remove函数只是将要删除的元素放到了容器的最后,不会删除元素。在STL所有容器中,唯一一个使用remove函数做了删除操作的是list容器的remove)SAMPLES:[cpp]viewplaincopyprint?1.intv3[10]={0,1,2,3,4,5,6,7,8,9};2.vectorintvecDeleted1(&v3[0],&v3[9]+1);3.4.typedefvectorint::iteratorVector_Iter;5.for(Vector_Iteriter=vecDeleted1.begin();iter!=vecDeleted1.end();++iter)6.{7.vecDeleted1.erase(remove(vecDeleted1.begin(),vecDeleted1.end(),*iter),vecDeleted1.end());8.}remove在一个给定范围内删除满足一定条件的元素,删除完成后,向量的大小不变,也就是说,它仅仅是将要删除的元素放到容器最后,而将所有未删除的元素前移而已。而且它返回的是指向那个移动元素位置之后的那个迭代器,所以上面的代码在使用remove之后,返回的迭代器指向向量的最后一个元素,也就是:--vecDeleted1.end()。然后在调用erase将向量的最后一个元素移除,由于最后一个元素后面就没有向量数据了,所以也不会往前移动任何数据,所以这样就能将向量