C++学习笔记(九)

第九章 顺序容器

1. 顺序容器(sequential container)为程序员提供了控制元素存储和访问顺序的能力。这种顺序不依赖于元素的值,而是与元素加入容器时的位置相对应。所有的顺序容器都提供了快速顺序访问元素的能力。

2. 顺序容器类型

vector 可变大小数组    deque  双端队列    list 双向链表    forward_list 单向链表      array 固定大小数组        string 与vector类型,专门保存字符

3. vector是顺序表,表示的是一块连续的内存,元素被顺序存储;list是双向连接表,在内存中不一定连续。

    C++中vectot和list的区别。         c++ list学习总结

4. 每个容器都定义在一个头文件中,文件名与类型名相同。

5. 迭代器范围:[begin, end)  前闭后开。其中begin和end必须指向相同的容器,end不能指向begin之前的位置。

    

6. 反向迭代器是一种反向遍历容器的迭代器,与正向迭代器相比,各种操作也发生颠倒。比如反向迭代器执行++操作,得到的是上一个元素。

7. 当不需要写访问时,应该使用cbegin和cend。 auto i=a.begin();  仅当a是const的时候,i是const_iterator。

8. 为了创建一个容器为另一个容器的拷贝,两个容器的类型以及元素类型必须匹配。比如: list<string> a(b);  创建a为b的拷贝,b必须是list<string>的。

    当传递迭代器参数来拷贝一个范围时,就不要求容器类型是相同的了。而且新容器和原容器中的元素类型也可以不同,只要能将拷贝的元素转换。比如:

    forward_list<string> word(a.begin(),a.end());  

9. 标准库array被定义时,除了指定元素类型,还需要指定容器大小,因为他是固定大小的类型:  array<int,10> a;

10.    swap(c1,c2)    c1.swap(c2)   交换c1 c2中的元素,必须是相同类型。    

          seq.assign(b,e)  将seq中的所有元素替换为b,e所表示的范围中的元素,b.e不能指向seq中的元素。

11. 除了无序关联容器外的所有容器都支持关系运算符> >= < <=。关系运算符两边的运算对象必须是相同类型的容器,且必须保存相同类型的元素。

      比较两个容器实际上是进行元素的逐对比较;如果两个容器都不是另一个容器的前子缀序列,比较结果取决于第一个不相等的元素的比较结果。

12. 向顺序容器中添加元素:以下操作实际上放入到容器中的的是对象值的一个拷贝,在调用成员函数时,会创建一个局部临时变量来将其压入容器。

      c.push_back(t)         c的尾部添加t,返回void

      c.push_front(t)          c的头部添加t,返回void

      c.insert(p,t)                在迭代器p指向的元素之前添加t,返回新添加的元素t的迭代器

      c.insert(p,n,t)             在迭代器p指向的元素之前插入n个t,返回添加的第一个元素的迭代器

      c.insert(p,b,e)            在迭代器p指向的元素之前插入迭代器b到e范围内的元素,返回第一个新添加元素的迭代器,若范围为空,返回p

13. 新标准引入三个新成员emplace_front, emplace, emplace_back,这些操作构造而不是拷贝元素。当我们调用emplace成员函数时,是将参数传递给元素类型的构造函数,emplace成员使用这些参数在容器管理的内存空间中直接构造元素。通常用于类对象。

14. 访问元素:  在解引用或者调用front、back之前检查下容器是否为空  if(!c.empty()) {...............}

       c.back()                      返回c中尾元素的引用

       c.front()                       返回c中首元素的引用

       c[n]  /   c.at(n)             返回c中下标为n的元素的引用,如果n越界,前者出错,后者抛出异常

15. 删除元素:

      c.pop_back()              删除c的尾元素,返回void

      c.pop_front()               删除c的首元素,返回void

      c.erase(p)                   删除迭代器p所指定的元素,返回一个被删元素之后元素的迭代器  

      c.erase(b,e)                删除迭代器b,e锁定范围内的元素,返回一个指向最后一个被删元素之后元素的迭代器 注意b,e范围是[b,e)  

      c.clear()                       删除c中所有元素,返回void

16. forward_list的操作:(必须有两个迭代器,一个指向我们要处理元素的迭代器begin,和一个指向其前驱的迭代器before_begin)

       a.before_begin()               返回指向链表首元素之前的不存在元素的迭代器

       a.insert_after(p,b,e)          在迭代器p之后插入迭代器b,e范围内的元素,返回一个指向最后一个插入元素的迭代器。

       a.erase_after(b,e)             删除从迭代器b,e内的元素,返回被删元素之后元素的迭代器

17. 向容器中添加元素和从容器中删除元素的操作可能会使指向元素的指针,引用或迭代器失效。当我们添加删除vector/string的元素后,或在deque中首元素之外任何位置添加删除元素后,原来end返回的迭代器总是会失效,因此,添加和删除元素的循环程序必须反复调用end,而不能在循环之前保存end返回的迭代器,一直当做容器末尾使用。

18. 习题:9.31:list的迭代器不能进行+-操作。所以要使用advance或distance。

     使用stl中的 advance和 distance 方法来进行iterator的加减              STL迭代器辅助函数——advance

19. vector和string的实现通常会分配比新空间需求更大的内存空间,预留这些空间作为备用,可用来保存更多的新元素。

20. 容器大小管理操作:

       c.reserve(n)            分配至少能容纳n个元素的内存空间

       c.capacity()             不重新分配内存的话c最多可以保存元素的数目

       c.shrink_to_fit()     将capacity()减少为与其本身size()相同大小

       reserve并不改变容器中元素的数量,仅仅影响vector预先分配多大的内存空间,当需要的内存空间超过当前容量时,reserve调用才会改变其容量;当需求小于或等于当前容量,它什么也不做。所以,调用reserve永远不会减少容器占用的内存空间。

       size是容器已经保存的元素的数量,capacity是在不分配新内存空间的前提下它最多可以保存元素的数量。所以capacity >= size

21. string类型的操作:

       构造string:                  string s(s2,pos2)            s是s2从下标pos2开始的字符的拷贝

       子字符串的操作:        s.substr(pos,n)                返回一个string ,包含s中pos开始的n个字符的拷贝

       修改string的操作:      s.insert(pos,args)            pos之前插入args指定的字符,返回第一个插入字符的迭代器

                                               s.erase(pos,len)               删除从位置pos开始的len个字符,返回一个指向s的引用

                                               s.assign(agrs)                  将s中的字符替换为args指定的字符,返回一个指向s的引用

                                               s.append(args)                 将args追加到s后,返回指向s的引用

                                               s.replace(range,args)      删除s中范围range内的字符,替换为args指定的字符,返回一个指向s的引用

       搜索操作:                    s.find(args)                        查找s中args第一次出现的位置

                                               s.rfind(args)                       查找s中args最后一次出现的位置

                                               s.find_first_of(args)          在s中查找agrs中任何一个字符第一次出现的位置

                                               s.find_last_of(args)           在s中查找agrs中任何一个字符最后一次出现的位置

                                               s.find_first_not_of(args)   在s中查找第一个不在agrs中的字符

                                               s.find_last_not_of(args)    在s中查找最后一个不在agrs中的字符

  搜索操作返回指定字符出现的下标,若未找到则返回npos.标准库将string::npos定义为一个const string::size_type类型,初始化为-1,是一个unsigned类型。

22. 除了顺序容器以外,标准库还定义了三个顺序容器适配器:stack(栈),queue(队列),priority_queue(优先级).

      一个适配器是一种机制,能使某种事物的行为看上去像另一种事物一样。一个容器适配器接受一种已有的容器类型,使其行为看上去像一种不同的类型。

      定义一个适配器:  stack<int> stk(deq);     从deq拷贝元素到stk

      默认情况下,stack和queue是基于deque实现的,priority_queue是基于vector之上实现的。

      stack定义在stack头文件中,queue和priority_queue定义在queue头文件中。

      queue使用一种先进先出FIFO的存储和访问策略。

      priority_queue允许为队列中的元素建立优先级。

      C++ 容器:顺序性容器、关联式容器和容器适配器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值