C++/STL_中vector基本操作测试代码,vector.erase()使用方法

时间:2022-03-20 04:25:23

通过vector我们可以减少类里的变量,比如一个类里存储了一种数据,但是不知道这种数据到底要存储个,我们常常使用(结构体数组/对象数组),加一个变量来表示 记录的数量。但是通过vector可以简化这个变量,因为vector里面有通用的size方法可以帮我们完成这个操作。


vector在尾部进行插入操作是高效的。vector只是简单地变长来适应新加入的元素。但在vector中间插入或删除元素是低效的,即在插入或删除的位置之后的整个部分都需要移动,因为vector在内存中占用的是连续的空间,和C/C++的源生数组一样。


测试代码:

#include <vector>
#include <iostream>

using namespace std;

struct Point{
int x;
int y;
};

ostream& operator<<(ostream &output, const Point &a){
return output << a.x << " " << a.y ;
}

int main(){
vector<Point> PointList;
vector<Point>::iterator iter;
//a[10] = 5;

Point a;
a.x = 5;
a.y = 5;

Point b;
b.x = 4;
b.y = 4;

PointList.push_back(a);
PointList.insert(PointList.begin()+1,b);
PointList.push_back(a);


//PointList._Pop_back_n(2); //delete the last two Points in PointList

cout << "traverse the PointList " << endl;
for (iter = PointList.begin(); iter != PointList.end(); iter++){
cout << *iter << endl;
}
cout << "The sizeof vector<Point> PointList is ";
cout << PointList.size() << endl;


cout << "output the Point which x == 5" << endl;
for (iter = PointList.begin(); iter != PointList.end(); iter++){
if ( 5 == (*iter).x )
cout << *iter << endl;
}

/*
cout << "erase all the Points which 5 == x" << endl;
for (iter = PointList.begin(); iter != PointList.end(); iter++){
if (5 == (*iter).x)
PointList.erase(iter);
}

cout << "traverse the PointList " << endl;
for (iter = PointList.begin(); iter != PointList.end(); iter++){
cout << *iter << endl;
}
*/

cout << endl << "Hello KeMeng~" << endl;

return 0;
}



C++/STL_中vector基本操作测试代码,vector.erase()使用方法


容器(vector,deque,list)的删除操作需要注意,可以通过erase方法删除满足条件的数据。但是以下代码会出错:(删除多个数据)

cout << "erase all the Points which 5 == x" << endl;
for (iter = PointList.begin(); iter != PointList.end(); iter++){
if (5 == (*iter).x)
PointList.erase(iter);
}
C++/STL_中vector基本操作测试代码,vector.erase()使用方法

原因:

原来是删除迭代器i后,i所指的元素已经失效了,然后给i++,它已经不在存在了。。。

链接:http://blog.csdn.net/u010003835/article/details/47421467


下面演示一下如何在vector 删除满足条件的数据:

	//两种方式
//方式一 : 通过erase的返回值找到下一个元素

for (iter = PointList.begin();iter!=PointList.end();){
if (5 == (*iter).x){
iter = PointList.erase(iter);
}
else
iter++;
}



bool equal_five(const Point & a);	//remove_if 需要的判断函数,remove_if返回满足删除条件的起始位置
//方式二 : 通过remove_if来返回边界再用 erase 删除
PointList.erase(remove_if(PointList.begin(), PointList.end(), equal_five), PointList.end());
bool equal_five(const Point & a){
return a.x == 5 ? true : false;
}



测试输出

C++/STL_中vector基本操作测试代码,vector.erase()使用方法



下面再展示 另一种错误的代码

	vector<Point>::iterator next = PointList.begin();
for (iter = PointList.begin(); ; ){
if (PointList.end() == next)
break;
++next;
if (5 == (*iter).x){
PointList.erase(iter);
}
iter = next;
}
然而结果会报错:

估计与vector实现有关,vector为数组,删除后进行前移,保存之前的位置没用。

c.end()由于模仿数组会发生变动。
错误代码

#include <iostream>
#include <list>
#include <vector>
#include <algorithm>


using namespace std;

struct p{
int x;
int y;
};

ostream& operator<<(ostream &output, const p &a){
return output << a.x << " " << a.y;
}




int main(){
vector<p> c;
p a,b;
a.x = 12;
a.y = 12;
b.x = 13;
b.y = 13;
c.push_back(a);
c.push_back(b);




for (vector<p>::iterator ak = c.begin(); ak != c.end(); ak++){
cout << (*ak) << endl;
}


cout << endl << c[1] << endl;


// todo insert items
vector<p>::iterator nextitr = c.begin();
for (vector<p>::iterator i = c.begin();;)
{
if (nextitr == c.end())
break;
++nextitr;
if ((*i).x>10)
{
// 如果有一个值大于10,删除之
c.erase(i);
}
i = nextitr;
}


cout << c.size() << endl;


return 0;
}

C++/STL_中vector基本操作测试代码,vector.erase()使用方法






但是对于list是可行的。  原因:list相当于链表

#include <iostream>
#include <list>
#include <vector>
#include <algorithm>


using namespace std;

struct p{
int x;
int y;
};

ostream& operator<<(ostream &output, const p &a){
return output << a.x << " " << a.y;
}




int main(){
list<p> c;
p a,b;
a.x = 12;
a.y = 12;
b.x = 13;
b.y = 13;
c.push_back(a);
c.push_back(b);




for (list<p>::iterator ak = c.begin(); ak != c.end(); ak++){
cout << (*ak) << endl;
}



// todo insert items
list<p>::iterator nextitr = c.begin();
for (list<p>::iterator i = c.begin();;)
{
if (nextitr == c.end())
break;
++nextitr;
if ((*i).x>10)
{
// 如果有一个值大于10,删除之
c.erase(i);
}
i = nextitr;
}

cout << c.size() << endl;


return 0;
}

C++/STL_中vector基本操作测试代码,vector.erase()使用方法

另一种更简便的方式

	for (list<p>::iterator i = c.begin(); i!=c.end();)
{
if ((*i).x > 10)
{
// 如果有一个值大于10,删除之
c.erase(i++);
}
else
i++;
}

另外一种方式
    std::list< int> List;
std::list< int>::iterator itList;
for( itList = List.begin(); itList != List.end(); )
{
if( WillDelete( *itList) )
{
itList = List.erase( itList);
}
else
itList++;
}




因此,我想到了是否对list进行下标访问,以下操作是非法的:

cout << c[1] << endl;

C++/STL_中vector基本操作测试代码,vector.erase()使用方法



但是该操作对于vector又是可行的,vector相当于数组,故可以通过下标的形式访问:

#include <iostream>
#include <list>
#include <vector>
#include <algorithm>


using namespace std;

struct p{
int x;
int y;
};

ostream& operator<<(ostream &output, const p &a){
return output << a.x << " " << a.y;
}




int main(){
vector<p> c;
p a,b;
a.x = 12;
a.y = 12;
b.x = 13;
b.y = 13;
c.push_back(a);
c.push_back(b);




for (vector<p>::iterator ak = c.begin(); ak != c.end(); ak++){
cout << (*ak) << endl;
}


cout << c[1] << endl;

/*
// todo insert items
vector<p>::iterator nextitr = c.begin();
for (vector<p>::iterator i = c.begin();;)
{
if (nextitr == c.end())
break;
++nextitr;
if ((*i).x>10)
{
// 如果有一个值大于10,删除之
c.erase(i);
}
i = nextitr;
}
*/

cout << c.size() << endl;


return 0;
}

C++/STL_中vector基本操作测试代码,vector.erase()使用方法