STL-vector用法小结

想得到容器中能保存的最大元素数量就可以用vector 类的成员函数 max_size() : 
 vector<shape>::size_type max_size = my_shapes.max_size(); 


当前容器的实际尺寸---- 已有的元素个数用size(): 

vector<shape>::size_type size = my_shapes.size(); 


可以用 capacity()来取得vector 中已分配内存的元素个数: 
vector<int> v; 
 vector<int>::size_type capacity = v.capacity(); 


vector 类似于数组,可以 使用下标[]访问: 
 vector<int> v(10); 
 v[0] = 101; 

注意到这里预先给 10 个元素分配了空间。


你也可以使用vector 提供的插入函数来动态的扩展容器。成员函数push_back()就在vector 的尾部添加了一个元素: 

 v.push_back(3); 

也可以用 insert()函数完成同样的工作: 
 v.insert(v.end(), 3); 
这里insert()成员函数需要两个参数:一个指向容器中指定位置的迭代器(iterator),一个待插入的元素。insert()将元素 插入到迭代器指定元素之前。 


 现在对迭代器(Iterator)做点解释。Iterator是指针(pointer) 的泛化,iterator 要求定义 operator*,它返回指定类型的值。Iterator 常常和容器联系在一起。例子: 

 vector<int> v(3); 
v[0] = 5; 
 v[1] = 2; 
 v[2] = 7; 
vector<int>::iterator first = v.begin(); 
vector<int>::iterator last = v.end(); 
 while (first != last) 
cout << *first++ << “ “; 
上面代码的输出是: 
 5 2 7 
begin()返回的是 vector中第一个元素的 iterator ,而 end()返回的并不是最后一个元素的 iterator,而是past the last element 。在STL 中叫past-the-end iterator 。 


你可以用以下的几种方法声明一个vector 对象

vector<float> v(5, 3.25); //初始化有5 个元素,其值都是3.25 

vector<float> v_new1(v); 

vector<float> v_new2 = v;  
vector<float> v_new3(v.begin(), v.end()); 
这四个vector 对象是相等的,可以用operator==来判断。 


其余常用的vector 成员函数有: 
empty() :判断vector 是否为空 
front() :取得vector 的第一个元素 
back() :取得vector 的最后一个元素 
pop_back() :去掉最后一个元素 
erase() :去掉某个iterator 或者iterator 区间指定的元素 

vector::erase():从指定容器删除指定位置的元素某段范围内的元素

vector::erase()方法有两种重载形式

如下:

iterator erase(   iterator _Where);

1.iterator erase(   iterator _First,   iterator _Last);

如果是删除指定位置的元素时:
返回值是一个迭代器,指向删除元素下一个元素;如果是删除某范围内的元素时:返回值也表示一个迭代器,指向最后一个删除元素的下一个元素;

  1. #include <vector> 
  2. #include <iostream> 
  3. int main( ) 
  4. using namespace std;  
  5. vector <int> v1;
  6. vector <int>::iterator Iter;
  7. v1.push_back( 10 );
  8. v1.push_back( 20 );
  9. v1.push_back( 30 );
  10. v1.push_back( 40 );
  11. v1.push_back( 50 );
  12. cout << "v1 =" ;
  13. for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) 
  14.   cout << " " << *Iter;
  15. cout << endl;
  16. v1.erase( v1.begin( ) );
  17. cout << "v1 =";
  18. for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) 
  19.   cout << " " << *Iter;
  20. cout << endl;
  21. v1.erase( v1.begin( ) + 1, v1.begin( ) + 3 );
  22. cout << "v1 =";
  23. for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) 
  24.   cout << " " << *Iter;
  25. cout << endl;
  26. }

Output
v1 = 10 20 30 40 50

v1 = 20 30 40 50
v1 = 20 50

(解释:删除的是Iter指针之间的数)

大家可以知道,需删除元素10只要指定该元素对应的迭代器传给erase就OK了;

那现在如果该容器中有两个元素10要怎么删除呢?

接着我做下修改,向容器中添加一新的元素10

  1. v1.push_back( 10 );

大多数初学者在不熟知erase的原理的时候,也会像我一样这样处理,
一一遍历容器找到元素值为10,然后一一删除

  1. for(Iter = v1.begin(); Iter != v1.end(); Iter++) 
  2.   if(*Iter == 10) 
  3.   { 
  4.       v1.erase(Iter);
  5.   } 
  6. }

当试着重新build程序后运行,会出现包含有如下信息的错误

_Myptr < ((_Myvec *)(this->_Mycont))->_Mylast

其他出现这种原因是没搞懂erase的原理,当调用erase()后Iter迭代器就失效了,变成了一野指针。

所以要处理这种问题,关键是要解决调用erase()方法后,Iter迭代器变成野指针的问题,

这个时候呢给他赋一个新的迭代器给他。

  1. for(Iter = v1.begin(); Iter != v1.end(); Iter++) 
  2.   if(*Iter == 10) 
  3.   { 
  4.       v1.erase(Iter);
  5.      Iter = v1.begin(); //当erase后,旧的容器会被重新整理成一个新的容器
  6.   } 
  7. }

重新Iter迭代器指定下一个元素.

上面那种方法是给Iter重新赋于新v1的begin迭代器。

还有一种方法是直接赋删除元素的下一个迭代器给Iter

实现方法的代码如下:

  1. for(Iter = v1.begin(); Iter != v1.end(); Iter++) 
  2.   if(*Iter == 10) 
  3.   { 
  4.    Iter = v1.erase(Iter);//Iter为删除元素的下一个元素的迭代器
  5.   //即第一次这段语句后Iter 会是20,大家可以通过debug调试出来查看下数值
  6.   } 
  7.   if(Iter == v1.end()) //要控制迭代器不能超过整个容器
  8.   { 
  9.    break;
  10.   } 
  11. }

vector<int> veci;
veci.push_back(1);
veci.push_back(2);
veci.push_back(3);
veci.push_back(4);
veci.push_back(5);
veci.push_back(3);
veci.push_back(2);
veci.push_back(3);

for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
      if( *iter == 3)
             veci.erase(iter);
}

乍一看这段代码,很正常。其实这里面隐藏着一个很严重的错误:当veci.erase(iter)之后,iter就变成了一个野指针,对一个野指针进行 iter++ 是肯定会出错的。

for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); iter++)
{
      if( *iter == 3)
             iter = veci.erase(iter);
}

这段代码也是错误的:1)无法删除两个连续的"3"; 2)当3位于vector最后位置的时候,也会出错(在veci.end()上执行 ++ 操作)

正确的代码应该为:

for(vector<int>::iterator iter=veci.begin(); iter!=veci.end(); )
{
     if( *iter == 3)
          iter = veci.erase(iter);
      else
            iter ++ ;
}


还有一种删除的办法:就是讲erase和remove配合使用~

vector中erase是真正删除了元素, 迭代器访问不到了。

algorithm中的remove只是简单的把要remove的元素移到了容器最后面,迭代器还是可以访问到的。

vector<int> array;
array.erase(remove(array.begin(),array.end(),6),array.end());
删除数组中所有元素等于6的元素

解释:remove只是把待删除的元素移位到了数据序列的尾部,而并未真正的删除元素, 
remove函数返回待删除序列的首个元素的迭代器 
比如说,123123,remove(1),那么序列变成了232311,返回一个迭代器,指向第一个1的位置,这是配合erase()函数,把这个迭代器作参数,可以把后,面两个1删除,数据序列变成了2323。

C++ Vector排序

 
 
  1. vector< int > vi ;   
  2. vi.push_back(1);  
  3. vi.push_back(3);  
  4. vi.push_back(0);  
  5. sort(vi.begin() , vi.end()); /// /小到大  
  6. reverse(vi.begin(),vi.end()) /// 从大道小 

顺序访问

 
 
    1. vector < int > vi ;   
    2. for( int i = 0 ; i < 10 ; i ++)  
    3. {  
    4. vi.push_back(i);  
    5. }   
    6. for(int i = 0 ; i < 10 ; i ++) /// 第一种调用方法  
    7. {  
    8. cout <<vi[i] <<" " ;   
    9. }  
    10. for(vector<int>::iterator it = vi.begin() ; it !=vi.end() ; it++) ///第二种调用方法  
    11. {  
    12. cout << *it << " " ;  
    13. }

寻找

 
 
  1. vector < int > vi ;   
  2. for( int i = 0 ; i < 10 ; i ++)  
  3. {  
  4. vi.push_back(i);  
  5. }   
  6. vector < int >::interator it = find(vi.begin() , vi.end,3) ;  
  7. cout << *it << endl ; ///返回容器内找到值的位置。

使用数组对C++ Vector进行初始化

 
 
  1. int i[10] ={1,2,3,4,5,6,7,78,8} ;   
  2. vector<int> vi(i+1,i+3); ///从第2个元素到第三个元素  
  3. for(vector <int>::interator it = vi.begin() ; it != vi.end() ; it++)  
  4. {  
  5. cout << *it <<" " ;   


Vector调用clear()之后,只会把size设置为0,而内存空间并没有释放。 vector 中的内建有内存管理,当 vector 离开它的生存期的时候,它的析构函数会把 vector 中的元素销毁,并释放它们所占用的空间,所以用 vector 一般不用显式释放 —— 不过,如果你 vector 中存放的是指针,那么当 vector 销毁时,那些指针指向的对象不会被销毁,那些内存不会被释放。

在《effective STL》和其实很多C++文章中都有指明,用clear()无法保证内存回收。但是swap技法可以。具体方法如下所示: 

vector<int> nums;
nums.push_back(1);
nums.push_back(1);
nums.push_back(2);
nums.push_back(2);
vector<int>().swap(nums); //或者nums.swap(vector<int> ()); 










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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值