C++ primer 顺序容器

最常用的顺序容器类型: vector类型
容器容纳特定类型对象的集合。标准库vector类型是一种顺序容器,将单一类型元素聚集起来成为容器,然后根据位置来存储和访问这些元素。
标准库定义了三种顺序容器类型:vector , list , deque (double ended queue).
容器只定义了少量的操作,大多数额外的操作由算法库提供。
容器类型的操作集合形成了以下类型:

  • 一些操作适用于所有的容器
  • 另外一些操作只适用于顺序或者关联容器
  • 还有一些操作只适用于顺序或者关联容器的一个子集

所有的容器都是类模板,要定义某种特殊的容器,必须在容器后面加一对尖括号,尖括号里面提供容器存放元素的类型。
容器类型一般使用默认构造函数,可以达到最佳的性能
除了默认构造函数,容器类型还提供了其他的构造函数
这里写图片描述
迭代器初始化时,不包括后一个迭代器指的值,因为迭代器范围是一个左闭区间
当不使用默认构造函数,而是使用其他构造函数初始化顺序容器时,必须指出该容器有多少个元素。

尽管不可以将一种容器内的元素复制给另一种容器,但系统允许通过传递一对迭代器间接实现该功能。不要求容器的类型相同,容器内元素的类型也可以不相同,只要他们互相兼容。
这里写图片描述

char *word[] = {“stately”,”plump”,”buck”}
c++中单引号是一个字符,双引号是字符串,c风格字符串
c++中操作字符串是通过它在内存中的首地址进行的,所以字符串常量的本质是地址
char word[]中,中括号的优先级高于 ,所以先是word[]结合,数组中的元素是char * ,

创建顺序容器时,可显式的指定容器大小和一个(可选的)元素初始化式,容器大小可以是常量或非常量表达式,元素初始化式必须是可用于初始化其元素类型的对象的值
创建容器时,可以只指定容器的大小,不提供元素初始化式时,标准库将为容器实现初始化,如果元素类型没有默认构造函数,必须显式的指定元素的初始化式。

容器内元素的类型约束:
容器的元素类型必须满足两个约束:
1. 元素类型必须支持赋值运算
2. 元素类型的对象必须可以复制
除了引用类型外,所有的内置或者复合类型都可以做元素类型,引用不支持一般意义的赋值运算,所以没有元素是引用的容器。
除了输入输出(IO)标准库类型,所有的标准库类型都是有效的容器元素类型,容器本身也可以。

容器操作的特殊要求:
支持复制和赋值是容器元素类型的最低要求,只有在同时指定每个元
素的初始化式时,才能使用给定容器大小的构造函数来创建同类型的容器对象

容器的容器

vector< vecotr<string> > lines; //vector类型的容器,容器的元素是string类型的vector对象
vector< vector<string>> lines; //这样是不对的,注意空格,分开两个>

和容器类型一样,所有的迭代器具有相同的接口
这里写图片描述
这里写图片描述

vector和deque容器的迭代器提供的额外操作
这里写图片描述
这里写图片描述

迭代器范围:
使用一对迭代器标记迭代器范围,这两个迭代器通常分别指向同一个容器的两个元素或者超出末端的一个元素。第二个迭代器从来都不是指向元素范围的最后一个元素, 而是指向最后一个元素的下一位置。
该范围的元素包括迭代器first指向的元素,以及从first开始一直到迭代器last指向的位置之前的所有元素。如果两个迭代器相等,则迭代范围为空。
[ first ,last ) 左闭合区间

使用左闭合区间的程序意义:
1.当first和last相等时,迭代范围为空
2.当first和last不相等时,迭代范围至少有一个元素,而且first指向该区间中的第一个元素。通过若干次自增运算,使first值不断增大,直到first == last为止。

使迭代器失效的容器操作
无法检查迭代器是否有效,也无法通过测试发现迭代器是否已经失效

每种顺序容器都定义了以下操作:

  • 在容器中添加元素
  • 在容器中删除元素
  • 设置容器大小
  • 获取容器内第一个和最后一个元素

    这里写图片描述
    这里写图片描述
    上述的每个操作都有两个版本,如果容器是 const 类型,就要在前面加上const_ 前缀,const_iterator等。

顺序容器中添加元素:
push_back,所有的顺序容器都支持 push_back 操作,在容器尾部添加一个元素
除了push_back 操作,list 和 deque 还提供了类似的操作 push_front , 在容器首部插入新的元素。

关键概念:容器元素都是副本
在容器中添加元素时,系统是将元素值复制到容器中,被复制的原始值和容器中的各个元素各不相关,当元素内元素值发生变化时,别复制的原始值不受影响,反之亦然。
这里写图片描述

在容器中指定位置添加元素
使用 insert

不要存储 end 操作返回的迭代器。添加或删除 deque 或
vector 容器内的元素都会导致存储的迭代器失效
为避免可以在每次插入后计算一个end的值

关系操作符
比较的容器必须具有相同的容器类型,且元素类型也必须相同

  • 如果两个容器具有相同的长度且所有的元素都相等,那么这两个元素就相等
  • 如果两个容器的长度不相同,较短的所有元素都等于较长的容器对应的元素,称较短的容器小于另一个容器
  • 如果两个容器不是对文的初始子序列,它们的比较结果取决于所比较的第一个不相等的元素

c++语言只允许两个容器做其元素类型定义的关系运算

这里写图片描述
这里写图片描述
resize操作可能会使迭代器失效

这里写图片描述
这里写图片描述

删除元素
这里写图片描述
vector容器不支持 pop_front 操作
find函数需要一对标记查找范围的迭代器以及一个在该范围内查找的值做参数,查找完成后返回一个迭代器,指向具有指定值的第一个元素
erase,pop_front,pop_back函数,使指向被删除元素的所有迭代器失效 ,对于vector容器,指向删除点后面的元素迭代器通常也会失效。对于deque容器,如果删除时不包含第一个元素或者最后一个元素那么该deque相关的所有迭代器都会失效

这里写图片描述

assign操作首先删除容器中所有的元素,然后将其参数所指向的新元素插入到该容器中
关于swap的一个重要问题是:该操作不会删除或者插入任何元素,而且保证常量时间内交换,由于容器内没有移动任何元素,因此迭代器不会失效

比起list和deque容器,vector的增长效率通常会很高

capacity和reserve成员
size是容器当前拥有的元素个数,而capacity是容器在必须分配新存储空间之间可以存储的元素总数
只要有剩余的容量,就不会重新分配内存,每当vector容器不得不重新分配内存时,会加倍当前容量的分配策略实现重新分配

容器的选用:vector和deque容器提供了对元素的快速随机访问,但是在容器任意位置插入或者删除元素,比在容器尾部插入或者删除开销大。list容器表示不连续的内存空间,允许向前和向后逐个遍历元素,插入或者删除list容器中一个元素不需要移动任何其他元素,list不支持随机访问,访问某个元素要求遍历涉及其他元素,在任何位置都能快速插入和删除,但随机访问开销大

选择容器的法则:
- 要求随机访问,则选择vector和deque
- 必须在中间位置插入或者删除元素,采用list
- 如果不是在中间,而是在首部或者尾部,使用deque
- 如果只需要在读取输入时,在中间位置插入元素,然后需要随机访问元素,可以考虑输入时将元素读入到一个list,接着对容器重新排序,使其适合顺序访问,然后将排序后的list容器复制到一个vector中

string 对象
这里写图片描述
string类型支持大多数的顺序容器的操作,在某些方面可以将string类型视作字符容器
….
string对象的一些操作

容器适配器
queue , priority_queue , stack
适配器是使一种事物的行为类似与另一种事物的行为的机制
使用适配器时必须包含相关的头文件
#include < stack >
#include < queue >

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>