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