vector容器学习

vector容器

小贴士:

  • a[3]==*(a+3)//a+3代表a的首地址偏离三个元素位置的地址,加上指针代表所指的具体内容

  • 一个程序退出编号不为0,则说明程序被异常终止

    Process finished with exit code 3

     

  1. vector 容器简介

    • vector是将元素置于动态数组中加以管理的容器

    • vector可以随机存取元素(支持索引值直接存取,用[]操作符或at方法)

    • vector尾部添加或移除元素非常关键,但是在中部或头部插入或移除元素比较费时

头文件
#include <vector>
  1. 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对象间拷贝正常
  1. 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;
    }
  1. 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
    }
  1. 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;
    }
  1. 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;
    }
  1. 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;
}

 

 

迭代器的失效

可能造成的原因

  1. 插入元素

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;
}
  1. 删除元素

    错误代码

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;
}
 
posted @ 2024-03-08 23:17  油爆虾  Views(6)  Comments(0Edit  收藏  举报