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值。
5.vector对象的带参数构造
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()); //用构造函数初始化容器vecIntB 11 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,4 11 vecIntB.assign(vecIntA.begin(), vecIntA.end());//用其它容器的迭代器作参数。vecIntB: 0,1,2,3,4 12 vecIntC.assign(3,9);//vecIntC: 9,9,9 13 vecIntD = vecIntA;//vecIntD: 0,1,2,3,4 14 vecIntC.swap(vecIntD);//vecIntC与vecIntD值交换。vecIntC: 0,1,2,3,4; vecIntD: 9,9,9 15 }
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容器内全部或部分元素”的对象。
- 迭代器指出容器中的一个特定位置。
- 迭代器就如同一个指针。
- 迭代器提供对一个容器中的对象的访问方法,并且可以定义了容器中对象的范围。
分类:
- 输入迭代器:也有叫法称之为“只读迭代器”,它从容器中读取元素,只能一次读入一个元素向前移动,只支持一遍算法,同一个输入迭代器不能两遍遍历一个序列。
- 输出迭代器:也有叫法称之为“只写迭代器”,它往容器中写入元素,只能一次写入一个元素向前移动,只支持一遍算法,同一个输出迭代器不能两遍遍历一个序列。
- 正向迭代器:组合输入迭代器和输出迭代器的功能,还可以多次解析一个迭代器指定的位置,可以对一个值进行多次读/写。
- 双向迭代器:组合正向迭代器的功能,还可以通过--操作符向后移动位置。
- 随机访问迭代器:组合双向迭代器的功能,还可以向前向后跳过任意个位置,可以直接访问容器中任何位置的元素。
双向迭代器支持的操作:
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(); //返回容器中最后一个元素之后的迭代器。
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;
- 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。