标准库类型vector

vector 与数组array,string的区别

array:存放数字
string:存放字符串
vector:存放其他类型,也被叫做容器(container)

vector简介

特点:表示对象的集合,所有对象类型都相同,存在一一对应的索引
头文件: #include <vector>
模板(template):
  类模板(class template)
  函数模板(function template)
vector是一个class template

模板不是类或者函数,模板可以看做是说明书
使用模板,实例化(instantiation):编译器根据模板创建类或函数的过程
注意事项:需要指明实例化何种类型
格式:vector<类型> 集合名

    vector<int> ivec;
    vector<char> cvec;
    vector<string> strvec; 
    vector<my_type> myvec;
    vector<vector<string>> vec_strvec;  //该向量的元素是vector对象
注意:vector容纳绝大多数类型的对象作为其元素,但引用不是对象,所以不存在包含引用的vector
老写法: vector<vector<int> >
C++11: vector<vector<int>>

定义和初始化vector对象

初始化关注的key point:
  对象类型
  对象个数
  vector name
默认初始化 / 赋值初始化 / 列表初始化
默认初始化
vector<T> vname
vector<int> v1; //空vector 对象类型int型 默认初始化
空vector的作用:定义一个空vector,然后当运行时 获取到元素的值后 逐一添加
赋值初始化
把一个vector对象的所有元素拷贝给另一个vector (副本)
key point:两个vector对象的类型必须相同
vector<int> v2 = v1;
vector<string> svec {sev2} //√
vector<string> svec{sev2} //√
列表初始化vector对象
利用花括号,将确定元素值赋给vector对象
常用于多个初始值的情况
    vector<string> svec ={"a","an","the"};
    vector<char> cvec ={'a','b','c','d'};
    
    vector<string> svec2 {"a","an","the"};
    vector<char> cvec2 {'a','b','c','d'};
    
    vector<char> ivec = {10,'x'}; //10个char型对象x
    
    vector<char> cvec_n =(5); //√包含了n=5个对象
    vector<int> int_n = (5); //? 这到底是包含了5个int型对象,还是1个5呢    

值初始化(value-initialized)

通常情况下,更在乎元素数量,而不是初始值
常见错误:vector<int> vi = 10;
问题:如何判断是初始值,还是元素数量呢?
解决方法:花括号还是圆括号
圆括号():次数
花括号{}:初始化的值
    vector<int> ivec_1 = {5};
    vector<int> ivec_n (5);
    
    vector<string> svec_1 = {"love"};
    vector<string> svec_n (5,"hello");
    
//×    vector<int> ivec_n =(5); 初始化容量的时候与赋值没什么关系
//×    vector<int> ivec_n =(5,"hello");
使用圆括号是构造(construct)vector对象
一个元素时候:说明vector对象容量
两个元素时候:说明vector对象容量和初值
注意事项:当构造时候,不能使用=赋值
使用花括号是初始化(list initialize)
初始化过程中,会尽可能的把花括号内的值当做元素初始值的列表来处理
注意事项:花括号内的值必须与vector元素类型相同

向vector对象中添加元素 ⭐

最常见的用法:创建一个空的vector,然后再添加对象
添加元素:
  .push_back():把一个值value,压入(push)到vector对象的尾端(back) -尾插法
注意事项:不能用下标形式添加元素,添加元素使用push_back下标访问,只能访问已经存在的元素
vector<int> ivec;
    for(int i = 0;i<100;i++){
        ivec.push_back(i);
    } 
范围for循环不应该改变其遍历序列的大小 P168原因
string word;
    vector<string> strvec;
    while(cin>>word){
        strvec.push_back(word);
    }
    for(int i=0;i<strvec.size();i++){
        cout<<strvec[i]<<" ";
    }

图片.png

vector常用操作

图片.png

vector<int> ivec {1,2,3,4,5};
    for(auto &i : ivec){ // 理解: i迭代器 
                         //:对容器迭代 
        i *= i;
    } 
    for(auto i:ivec){
        cout<< i <<" "; 
    }
    cout<<endl; 

利用vector完成分段统计

    /*输出成绩,判断在哪个分区 
     0-100 有11个分区
     0~9,10~19......90~99,100 */ 
    vector<unsigend> socore (11,0);//分段处理
    unsigned grade;
    while(cin>>grade){
        if(grade <= 100)
        ++scores[grade/10]; 
        /*    grade/10 确定分区索引
            scores[grade/10] 对应分区的统计数
            ++scores[grade/10] ++ 
            
            结果: 42 65 95 100 39 
        */
    } 

Akuaner
7 声望3 粉丝