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

12 篇文章 0 订阅

通过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;
}





容器(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);
	}


原因:

原来是删除迭代器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;
}



测试输出



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

	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;
}







但是对于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;
}


另一种更简便的方式

	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;




但是该操作对于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;
}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值