vector

来源:互联网 发布:java中instanceof用法 编辑:程序博客网 时间:2024/06/07 00:49

STL--vector(2)

一、容器的分类

容器有序列式容器(Sequence containers)和关联式容器(Associated containers)
序列式容器:每个元素的位置取决于元素被插入的时机,被插入时设置的位置,和元素值本身无关。
序列式容器有vector、deque、list

关联式容器:元素位置取决于特定的排序准则,和插入顺序无关。
关联式容器有set、multiset、map、multimap

二、vector

1.vector简介

  • vector是将元素置于一个动态数组中加以管理的容器。
  • vector可以随机存取元素(支持索引值直接存取, 用[]操作符或at()方法)。
  • vector尾部添加或移除元素非常快速。但是在中部或头部插入元素或移除元素比较费时。

使用之前准备:

#include <vector>  using namespace std;

2.vector对象的默认构造

复制代码
 1 #include <vector> 2  3 using namespace std; 4  5 void main() 6 { 7     vector<int> vecInt;         //一个存放int的vector容器。 8     vector<float> vecFloat;     //一个存放float的vector容器。 9     vector<string> vecString;   //一个存放string的vector容器。10 11     class CA{};12     vector<CA*> vecpCA;            //用于存放CA对象的指针的vector容器。13     vector<CA> vecCA;            //用于存放CA对象的vector容器。由于容器元素的存放是按值复制的方式进行的,所以此时CA必须提供CA的拷贝构造函数,以保证CA对象间拷贝正常。14 }
复制代码

用于存放CA对象的vector容器。由于容器元素的存放是按值复制的方式进行的,所以此时CA必须提供CA的拷贝构造函数,以保证CA对象间拷贝正常。

3.vector末尾的添加移除操作

vector.push_back(elem); //在容器尾部加入一个元素。
vector.pop_back();               //移除容器中最后一个元素

4.vector的数据存取

vec.at(idx);  //返回索引idx所指的数据,如果idx越界,抛出out_of_range异常。
vec[idx];  //返回索引idx所指的数据,越界时,运行直接报错。
例如:假设vecInt是用vector<int> 声明的,且已包含按顺序的1,3,5,7,9值;此时vecInt.at(2)==vecInt[2]==5。若运行代码vecInt.at(2)=8,或者运行vecInt[2]=8,则vecInt就包含按顺序的1,3,8,7,9值。

vector.front();   //返回第一个数据。
vector.back();  //返回最后一个数据。

5.vector对象的带参数构造

vector(beg,end);    //构造函数将[beg, end)区间中的元素拷贝给本身。注意该区间是左闭右开的区间。
vector(n,elem);   //构造函数将n个elem拷贝给本身。
vector(const vector &vec);  //拷贝构造函数。
复制代码
 1 #include <vector> 2  3 using namespace std; 4  5 void main() 6 { 7     int iArray[] = {0,1,2,3,4}; 8  9     vector<int> vecIntA(iArray, iArray+5);//将iArray数组的值给vecIntA                    10     vector<int> vecIntB (vecIntA.begin() , vecIntA.end());   //用构造函数初始化容器vecIntB11     vector<int> vecIntC(3, 9); //此代码运行后,容器vecIntB就存放3个元素,每个元素的值是9。12     vector<int> vecIntD(vecIntA);13 }
复制代码

6.vector的赋值

vector.assign(beg,end);//将[beg, end)区间中的数据拷贝赋值给本身。注意该区间是左闭右开的区间。
vector.assign(n,elem);//将n个elem拷贝赋值给本身。
vector& operator=(const vector  &vec);//重载等号操作符
vector.swap(vec);// 将vec与本身的元素互换。

复制代码
 1 #include <vector> 2  3 using namespace std; 4  5 void main() 6 { 7     vector<int> vecIntA, vecIntB, vecIntC, vecIntD; 8     int  iArray[] = {0,1,2,3,4}; 9 10     vecIntA.assign(iArray,iArray+5);//vecIntA: 0,1,2,3,411     vecIntB.assign(vecIntA.begin(), vecIntA.end());//用其它容器的迭代器作参数。vecIntB: 0,1,2,3,412     vecIntC.assign(3,9);//vecIntC: 9,9,913     vecIntD = vecIntA;//vecIntD: 0,1,2,3,414     vecIntC.swap(vecIntD);//vecIntC与vecIntD值交换。vecIntC: 0,1,2,3,4; vecIntD: 9,9,915 }
复制代码

7.vector的大小

vector.size();//返回容器中元素的个数
vector.empty();//判断容器是否为空
vector.resize(num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
vector.resize(num, elem);//重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

 8.vector的插入

vector.insert(pos,elem);//在pos位置插入一个elem元素的拷贝,返回新数据的位置。
vector.insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
vector.insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。

复制代码
 1 #include <vector> 2  3 using namespace std; 4  5 void main() 6 { 7     vector<int> vecA; 8     vector<int> vecB; 9 10     vecA.push_back(1);11     vecA.push_back(3);12     vecA.push_back(5);13     vecA.push_back(7);14     vecA.push_back(9);15 16     vecB.push_back(2);17     vecB.push_back(4);18     vecB.push_back(6);19     vecB.push_back(8);20     21     vecA.insert(vecA.begin(), 11);                            //{11, 1, 3, 5, 7, 9}22     vecA.insert(vecA.begin()+1, 2, 33);                        //{11,33,33,1,3,5,7,9}23     vecA.insert(vecA.begin(), vecB.begin(), vecB.end());    //{2,4,6,8,11,33,33,1,3,5,7,9}24 }
复制代码

9.vector的删除

vector.clear();//移除容器的所有数据
vec.erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
vec.erase(pos);//删除pos(迭代器)位置的数据,返回下一个数据的位置。

三、迭代器

1.简介

  • 迭代器是一个“可遍历STL容器内全部或部分元素”的对象。
  • 迭代器指出容器中的一个特定位置。
  • 迭代器就如同一个指针。
  • 迭代器提供对一个容器中的对象的访问方法,并且可以定义了容器中对象的范围。

分类:

  1. 输入迭代器:也有叫法称之为“只读迭代器”,它从容器中读取元素,只能一次读入一个元素向前移动,只支持一遍算法,同一个输入迭代器不能两遍遍历一个序列。
  2. 输出迭代器:也有叫法称之为“只写迭代器”,它往容器中写入元素,只能一次写入一个元素向前移动,只支持一遍算法,同一个输出迭代器不能两遍遍历一个序列。
  3. 正向迭代器:组合输入迭代器和输出迭代器的功能,还可以多次解析一个迭代器指定的位置,可以对一个值进行多次读/写。
  4. 双向迭代器:组合正向迭代器的功能,还可以通过--操作符向后移动位置。
  5. 随机访问迭代器:组合双向迭代器的功能,还可以向前向后跳过任意个位置,可以直接访问容器中任何位置的元素。

双向迭代器支持的操作:
  it++,  ++it,    it--,   --it,*it, itA = itB,itA == itB,itA != itB。其中list,set,multiset,map,multimap支持双向迭代器。
随机访问迭代器支持的操作:
  在双向迭代器的操作基础上添加 it+=i, it-=i, it+i(或it=it+i),it[i], itA<itB,   itA<=itB,  itA>itB,  itA>=itB  的功能。其中vector,deque支持随机访问迭代器。

2.vector与迭代器的配合使用

1)

  • vec.begin();  //返回容器中第一个元素的迭代器。
  • vec.end();  //返回容器中最后一个元素之后的迭代器。
 例如:vecInt是用vector<int>声明的容器,假设已经包含了按顺序的1,3,5,7,9元素。
vector<int>::iterator   it;  //声明容器vector<int>的迭代器。
运行 it=vecInt.begin();    //此时*it==1。
运行++it;  // 或者it++;  此时*it==3,前++的效率比后++的效率高,前++返回引用,后++返回值。
运行it += 2;   //此时*it==7。
运行it = it +1;  //此时*it=9。
运行++it;   //此时it==vecInt.end();  此时不能再执行*it;
 
2)
  • vec.rbegin();  //返回容器中倒数第一个元素的迭代器。
  • vec.rend();   //返回容器中倒数最后一个元素之后的迭代器。

例如:  vecInt是vector<int>声明的容器,已包含按顺序的1,3,5,7,9元素。现要求逆序打印这些元素。

3)

  • vector<int>::const_iterator
  • vector<int>::const_reverse_iterator

这两种分别是

  • vector<int>::iterator
  • vector<int>::reverse_iterator

的只读形式,使用这两种迭代器时,不会修改到容器中的值。
备注:不过容器中的insert和erase方法仅接受这四种类型中的iterator,其它三种不支持。《Effective STL》建议我们尽量使用iterator取代const_iterator、reverse_iterator和const_reverse_iterator。