Skip to content

Latest commit

 

History

History
167 lines (128 loc) · 6.28 KB

顺序容器.md

File metadata and controls

167 lines (128 loc) · 6.28 KB

一个容器就是一些特定类型对象的集合

  • vector:可变大小的数组,支持随机访问,在尾部之外的位置插入或删除元素可能会很慢;通常,使用vector是最好的选择
  • list和forward_list在任何位置插入或删除元素都很快
  • 如果要求随机访问元素,应使用vector 或 deque

一个迭代器范围由一对迭代器表示(begin, end)

  • end可以与begin指向相同的位置,但不能指向begin之前的位置

  • end指向容器中尾元素之后的位置

  • 类型别名: 通过类型别名,我们可以在不了解容器中元素类型的情况下使用它

  • list<string> a = {"what", "is", "the", "matter"};
    auto it1 = a.begin(); // list<string>::iterator
    auto it2 = a.rbegin();// r表示返回反向迭代器,list<string>::reverse_iterator
    auto it3 = a.cbegin();// c表示返回const迭代器,list<string>::const_iterator
    auto it4 = a.crbegin();// list<string>::const_reverse_iterator
  • 可以将普通的iterator转换成const_iterator, 反之不行

  • 每个容器类型都定义了一个默认构造函数

  • 创建一个容器为另一个容器的拷贝,两个容器的类型及其元素类型必须匹配。不过,当传递迭代器参数来拷贝一个范围时,就不要求容器类型相同

    list<string> animals = {"cat", "dog", "pig"};
    vector<const char*> ac = {"a", "an", "the"};
    list<string> animals_s(animals);
    forward_list<string> words(ac.begin(), ac.end());
  • 列表初始化

    vector<int> ievc(10,-1); //10个int元素,每个元素都初始化为 -1
    list<string> svec(10,"hi"); //10个string元素,每个都初始化为"hi"
    forward_list<int> ivec(10); //10个元素,每个都从初始化为 0
    deque<string> svec(10); // 10个元素,每个都是空 tring
  • *** 只有顺序容器的构造函数才接受大小参数,关联容器不支持***

  • 当定义一个array时,除了定义类型,还要指定大小;一个默认构造的array是非空的

    array<int,42> a;
    array<int, 3> a2 = {1,2,3};
    array<int, 3> a3 = {1}; //a3[0]为1,其余元素为0
    array<int, 3> a4 = a2; //只要数组类型匹配即合法
  • assign不适用于关联容器和array

    list<string> names;
    vector<const char*> oldstyle;
    names = oldstyle ; // 错误!因为容器类型不匹配
    names.assign(oldstyle.cbegin(), oldstyle.cend()); // 因为oldstyle是const,所以用cbegin()
  • 除了array外, swap不对任何元素进行拷贝、删除或插入操作,因此,可以保证在常数时间内完成

  • 容器的关系运算,实际上是使用元素的关系运算完成的

  • 向一个vectorstringdeque插入元素会使所有指向容器的迭代器、引用和指针失效

  • push_back在容器尾部创建新的元素

  • vectorstring不支持push_front

  • insert将元素插入到迭代器所指位置之前

    vector<string> svec;
    list<string> slist;
    // 等同于 slist.push_front("hello");
    slidt.insert(slist.begin(),"hello");
    svec.insert(svec.begin(),"hello");
    svec.insert(svec.end(),10,"action"); // 将10个元素插入到svec的末尾,这些元素都被初始化为”action“
    
    vector<string> color = {"red","blue","yellow"};
    // 将color的最后两个元素添加到slist的开始位置
    slist.insert(slist.begin(),color.end()-2,color.end());
    slist.insert(slist.end(),{"red","blue","green"});

访问元素

  • 每个顺寻容器都有一个front成员函数,除forward_list之外,都有一个back成员函数

    // 访问back和front返回的是引用
    if (!(c.empty)){
        c.front() = 42; // 将 42 赋予c中的第一个元素
        auto &v = c.back(); // 获得指向最后一个元素的引用
        v = 1024; // 改变c中的元素
        auto v2 = c.back(); // v2不是引用,它是 c.back()的一个拷贝
        v2 = 0; // 未改变 c 中的值
    }
  • 如果希望确保下标是合法的,可以使用at成员函数,如果越界,会抛出异常out_of_range

    vector<string> svec; // 空 vector
    cout<<svec[0]<<endl; // 运行时错误,svec中没有元素
    cout<<svrc.at(0); // 抛出一个 out_of_range 异常
  • vector和string不支持push_front、pop_front; forward_listr不支持pop_back

  • erase产出容器中指定位置的元素

    list<int> lst = {0,1,2,3,4,5,6,7,8,9};
    auto it = lst.begin(); // it指向容器首元素的地址
    while (it != lst.end())
        if (*it % 2) // (*it) 代表it指向的地址的值
            it = lst.erase(it); // 删除此元素, it指向改被删除元素的后一个元素
    	else
            ++it;
    lst.clear(); // 删除容器中所有元素
    lst.erase(lst.begin(),lst.end());
  • forward_list中插入或删除元素的操作

    lst.before_begin();
    lst.cbefore_begin(); // 返回指向链表首元素的之前不存在的元素的迭代器,此迭代器不能解引用
    lst.insert_after(p,n,t); // 在之后的位置插入元素,t是一个对象,n是数量
    lst.insert_after(p,b,e); // b和e是表示范围的一对迭代器
    lst.insert_after(p,li); // li是一个花括号列表
    emplace_after(p,args); // 使用args在p指定的位置之后创建一个元素
    lst.erase_after(p); // 删除p指向的位置之后的元素
    lst.rease_after(b,e); // 删除b指向的,直到e之前的元素 
    forward_list<int> flst = {1,2,3,4,5,6};
    auto prve = flst.before_begin(); // 表示flst的首前元素
    auto curr = flst.begin(); // 表示flst的第一个元素
    while (curr != flst.end()){
        if (*curr % 2)
            // 当前元素未奇数,则删除;若要删除当前元素,需要先指向其前驱,之后再		erase_after(prve)
            curr = flst.erase_after(prve); // 返回一个指向被删除的元素之后元素的迭代器
        else{
            prve = curr;
            ++curr;
        }
    }
    • shrink_to_fit 只适用于 vector、string和deque
    • capacity():不重新分配内存的情况下 ,容器可以保存多少元素
    • reverse(n):分配至少能容纳n个元素的空间
    • string: s.replace(11,3,"3th") 从位置11开始,删除三个元素,并插入3th