vector容器学习
小贴士:
-
a[3]==*(a+3)//a+3代表a的首地址偏离三个元素位置的地址,加上指针代表所指的具体内容
-
一个程序退出编号不为0,则说明程序被异常终止
Process finished with exit code 3
-
vector 容器简介
-
vector是将元素置于动态数组中加以管理的容器
-
vector可以随机存取元素(支持索引值直接存取,用[]操作符或at方法)
-
vector尾部添加或移除元素非常关键,但是在中部或头部插入或移除元素比较费时
-
头文件
#include <vector>
-
vector对象的默认构造
vector采用模板类实现,vector对象的默认构造形式
vector<T> vecT;//也就是vector<数据类型> 容器名
vector<int> vecInt;//一个存放int的vector容器,容器名为vetInt
vector<string> vecString;//一个存放string的vector容器
... //尖括号内还可以设置指针类型或自定义类型
class CA{};
vector<CA*> vecpCA; //用于存放CA对象的指针的vector容器
vector<CA> vecCA; //用于存放CA对象的vector容器,由于容器元素的存放是按值复制的方式进行的,所以此时CA必须提供CA的拷贝构造函数,以保证CA对象间拷贝正常
-
vector对象的带参数构造
-
vector(beg,end);//构造函数将[beg,end)区间中的元素拷贝给本身。(注意该区间左闭右开)
-
vector(n,elem);//构造函数将n个elem拷贝给本身
-
vector(const vector &vec)//拷贝构造函数
int main()
{
int iarr[]={1,2,3,4,5};
vector<int> v1(iarr,iarr+5);//数组名代表首地址
vector<int> v2(3,10);//存储三个10
for(int i=0;i<3;i++){
cout << v2[i] <<;
}
vector<int> v3(v1);
vector<int> v4=v1;//效果和上句相同
return 0;
}
-
vector的赋值
assign函数
-
(1)vector.assign(beg,end);//将[beg,end)区间中的数据拷贝赋值给本身。注意该区间是左闭右开的区间
-
(2)vector.assign(n,elem);将n个elem拷贝赋值给本身
-
(3)vector& operator=(const vector &vec);//重载等号操作符
-
(4)vector.swap(vec);//将vec与本身的元素互换
int main()
{
vector<int> vetIntA,vetIntB,vetIntC,vetIntD;
int aArray[]={0,1,2,3,4};
//将数组iArray中的所有元素赋值给vecIntA容器
vetIntA.assign(iArray,iArray+5);//(1)的用法1:已知了一个数组
for(int i=0;i<vecIntA.size();i++){ //如果vecIntA原本有元素会清除原有元素(原来有十个元素最终也会变成只有五个)
cout << vecIntA[i] << " ";
}
cout << endl;
//效果是将vetIntA的所有元素赋值给vecIntB
//begin和end都是函数
vecIntB.assign(vecIntA.begin(),vecIntA.end());//(1)的用法2:已知了一个容器;begin()指向的是容器中第0个元素,end指向的是最后一个元素的下一个元素
vecIntB.assign(vecIntA.begin()+2,vecIntA.end()-1);//打印出2,3
vecIntB.swap(vecIntC);//(4)的用法:将两个容器的元素交换
vecIntD=vecIntC;//(3)的用法,将vecIntC的元素赋值给vecIntD
}
-
vector的大小
-
vector.size();//返回容器中元素个数
-
vector.empty();//判断容器是否为空,若为空返回
-
vector.resize(num);//重新指定容器的长度为num,若容器变长,则以默认值(即0)填充新位置;若容器变短,则末尾超出容器长度的元素被删除(vector.resize(a,b);a为容器指定长度,此时容器变长,b为变长部分指定元素)
-
vector.
int main()
{
vector<int> v1;
//第一个用法
cout << "v1.size: " << v1.size() << endl;//输出:v1.size: 0
if(v1.empty())//判断语句是否为空
{
cout << "v1 is empty" << endl;//输出:v1 is empty
}
//第二个用法
int iArray[]={0,1,2,3,4};
v1.assigh(iArray,iArray+5);
v1.resize(10);//将容器变长
for(int i=0;i<v1.size();i++)
cout << v1[i] << " ";
cout << endl;//输出:0 1 2 3 4 0 0 0 0 0
v1.resize(3);//将容器变短
for(int i=0;i<v1.size();i++)
cout << v1[i] << " ";
cout << endl//输出:0 1 2
//将容器长度变长,并扩展出来的元素为指定的值
v1.resize(10,100);//将容器变短
for(int i=0;i<v1.size();i++)
cout << v1[i] << " ";//0 1 2 100 100 100 100 100 100 100
return 0;
}
-
vector元素的访问方式
使用下标访问vector容器中的元素越界可能会导致程序异常终止
int main()
{
int a[]={1,2,3,4};
vector<int> v1(a,a+4);
for(int i=0;i<v1.size();i++)
cout << v[i] << " ";
cout << endl;
v1[5]=100;//成功写入一百,程序正常,仍然return 0
v1[8]=100;//无权限访问此地址,返回值不正常,程序异常终止
//解决办法
v1.at[8]==100;//直接打印出错信息
return 0;
}
解决方法(两种程序都会异常终止)
-
vec.at(idx);//返回索引(可以理解为下标)idx所指的数据,如果idx越界,抛出out_of_range异常更推荐
-
vec[idx];//返回索引idx所指的数据,越界时运行不会明确打印出错信息
-
vector末尾添加移除操作
int main()
{
int a[]={1,2,3,4};
vector<int> v1(a,a+4);
//从末尾添加一个元素
v1.push_back(10);
v1.push_back(11);
for(int i=0;i<v1.size();i++)
cout << v1[i] << " ";
cout << endl;//输出:1 2 3 4 10 11
//删除末尾的元素
v1.pop_back();
for(int i=0;i<v1.size();i++)
cout << v1[i] << " ";
cout << endl;//输出:1 2 3 4 10
return 0;
}
-
vector的插入
-
vector.insert(pos,elem);//在pos位置插入一个elem元素的拷贝,返回新数据的位置
-
vector.insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值
-
vector.insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值,begin为开始元素的下标,end为结束元素下一个元素的下标
int main()
{
int a[]={1,2,3,4};
vector<int> v1(a,a+4);
v1.push_back(10);
//在指定的位置插入一个指定元素
v1.insert(v1.begin()+3,100);//注意:第一个参数不能为下标,应该为指针
for(int i=0;i<v1.size();i++)
cout << v1[i] << " ";
cout << endl;//输出:1 2 3 100 4 10
//在指定位置插入多个元素
v1.insert(v1.begin()+3,3,1000);//在下标为3的位置插入3个1000
for(int i=0;i<v1.size();i++)
cout << v1[i] << " ";
cout << endl;//输出:1 2 3 1000 1000 1000 100 4 10
int b[]={40,50,60,70,80,90};
//将数组指定区间中的元素插入到指定位置
v1.insert(v1.begin()+7,b+1,b+5);
for(int i=0;i<v1.size();i++)
cout << v1[i] << " ";
cout << endl;//输出:1 2 3 1000 1000 1000 100 50 60 70 80 4 10
vector<int> v2(b,b+6);
v1.insert(v1.begin()+7,v2.begin()+1,v2.begin()+4);//将v2的50,60,70插入v1中
for(int i=0;i<v1.size();i++)
cout << v1[i] << " ";
cout << endl;//输出:1 2 3 1000 1000 1000 100 50 60 70 50 60 70 80 4 10
}
vector容器中的iterator类型
-
vector<int>::iterator iter;//变量名为iter
-
vector容器的迭代器属于"随机访问迭代器"(自增,自减,+n,-n):迭代器一次可以移动多个位置
int main()
{
vector<int> vecIntA;
int iArray[]={0,1,20,30,40};
vecIntA.assign(iArray,iArray+5);
//构造一个迭代器对象
vector<int>::iterator iter;
//让迭代器指向vecIntA容器中的第一个元素
it = vecIntA.begin();//可以把it看作一个指针
cout << *it << endl;//输出:0
//通过循环的方式使用迭代器遍历vecIntA中所有元素
for(it = vecIntA.begin();it != vecIntA.end();it++){
cout << *it << " ";
}
cout << endl;
//迭代器可随机访问容器元素
it = vecIntA.begin();
it = it + 2;
cout << *it << endl;//输出:20
return 0;
}
迭代器的失效
可能造成的原因
-
插入元素
int main()
{
vector<int> v;
v.pushback(1);//迭代器中插入1
v.pushback(2);
v.pushback(3);
v.pushback(4);
vector<int>::iterator it = v.begin() + 3;
cout << *it << endl;//输出:4
v.insert(it,8);//insert会返回一个新的有效的迭代器
//插入元素后导致迭代器失效,因为原迭代器没有分配足够空间,原迭代器会另外寻一片空地用来存储,原地址会被删除或释放,但it仍指向原地址
cout << *it << endl;//输出:0
//应给迭代器重新赋值为insert函数的返回值可解决上述问题
it=v.insert(it,8);//将it指向现地址
cout << *it << endl;//输出:8
for(it=v.begin();it != v.end();it++){
cout << *it << " ";//输出:1 2 3 8 4
}
return 0;
}
-
删除元素
错误代码
int main()
{
//删除元素后导致迭代器失效
vector<int> cond={1,2,3,3,3,3,4,5,6};
vector<int>::iterator it;
for(it=cond.begin();it!=cond.end();i++){
if(*it==3){
cond.erase(it);//删除此元素
}
}
//只有第二个和第四个3被删除,因为有it++
for(it=cond.begin();it!=cond.end();it++){
cout << *it << " ";//输出:1 2 3 3 4 5 6
}
cout << endl;
return 0;
}
正确代码(不推荐):
int main()
{
vector<int> cond={1,2,3,3,3,3,4,5,6};
vector<int>::iterator it;
for(it=cond.begin();it!=cond.end();){
if(*it==3){
vector<int>::iterator it1;
it1=cond.erase(it);//删除此元素且定义it1迭代器可证明erase函数与insert函数相同都有返回值,但有的编译器会认为it迭代器已失效可能无法正常运行,所以推荐下面的方法
cout << *it1 << endl;//输出:3
//3
//3
//4
else{
it++;//与错误代码相比改变部分:只有没有找到需要删除的元素才要++
}
}
}
//只有第二个和第四个3被删除,因为有it++
for(it=cond.begin();it!=cond.end();it++){
cout << *it << " ";//输出:1 2 3 3 4 5 6
}
cout << endl;
return 0;
}
正确代码(推荐)
int main()
{
vector<int> cond={1,2,3,3,3,3,4,5,6};
vector<int>::iterator it;
for(it=cond.begin();it!=cond.end();){
if(*it==3){
it=cond.erase(it);//删除此元素且再次使用it迭代器可证明erase函数可返回新的,有效的迭代器
else{
it++;//与错误代码相比改变部分:只有没有找到需要删除的元素才要++
}
}
}
//只有第二个和第四个3被删除,因为有it++
for(it=cond.begin();it!=cond.end();it++){
cout << *it << " ";//输出:1 2 3 3 4 5 6
}
cout << endl;
return 0;
}