C++ 9.1 顺序容器-----vector、list、deque

来源:互联网 发布:淘宝清洗过期了怎么办 编辑:程序博客网 时间:2024/05/22 17:19

简介

  • C++提供了使用抽象进行高效率编程的方式。标准库就是一个很好的例子,标准库定义了许多容器类以及一系列泛型算法,使得程序员可以更加简洁、抽象和有效的编写程序。

  • 容器都是由标准库定义的,我们可以将string类型看作仅包含字符的特殊容器,string类型提供大量的容器操作。(9章)

  • 标准库还提供了几种关联容器,关联容器元素不是顺序排列,而是按键(key)排序的。(10章)

  • 泛型算法,这些算法通常作用于容器或序列中某一范围的元素。算法库提供了各种各样经典算法的有效实现,像查找、排序及其他常见的算法任务–复制算法。(11章)

  • 标准库定义了三种顺序容器类型

    • vector
    • list
    • deque(是双端队列的简写)
  • 他们的差别在于访问元素的方式,以及添加或删除元素相关操作的运行代价。

  • 顺序容器适配器包括:

    • stack
    • queue
    • priority_queue
  • 为了定义一个容器类型的对象,必须先包含相关的头文件,即以下头文件之一:

//三种顺序容器的头文件#include<vector>#include<list>#include<deque>

===========================================================================================================

第二部分 标准库定义的容器与算法 序

  • C++提供了使用抽象进行高效率编程的方式。标准库就是一个很好的例子,标准库定义了许多容器类以及一系列泛型算法,使得程序员可以更加简洁、抽象和有效的编写程序。

  • 容器都是由标准库定义的,我们可以将string类型看作仅包含字符的特殊容器,string类型提供大量的容器操作。(9章)

  • 标准库还提供了几种关联容器,关联容器元素不是顺序排列,而是按键(key)排序的。(10章)

  • 泛型算法,这些算法通常作用于容器或序列中某一范围的元素。算法库提供了各种各样经典算法的有效实现,像查找、排序及其他常见的算法任务–复制算法。(11章)

  • 为容器提供通用接口是设计库的目的。如果两种容器提供相似的操作,则为他们定义的这个操作应该完全相同。

  • 容器提供的操作和算法是一致定义的,这使得学习标准库更加容易:只需要理解一个操作如何工作,就能将该操作应用于其他的容器。

一、顺序容器

1、顺序容器、顺序容器适配器

  • 容器容纳特定类型对象的集合。我们使用过一种容器类型:标准库vector类型,这是一种顺序容器。它将单一类型元素聚集起来称为容器,然后根据位置来存储和访问这些元素,这就是顺序容器。

  • 顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定

  • 标准库定义了三种顺序容器类型

    • vector
    • list
    • deque(是双端队列的简写)
  • 他们的差别在于访问元素的方式,以及添加或删除元素相关操作的运行代价。

  • 标准库还提供了三种容器适配器(adaptor):适配器是根据原始的容器类型所提供的操作,通过定义新的操作接口,来适应基础的容器类型。

  • 顺序容器适配器包括:

    • stack
    • queue
    • priority_queue
      这里写图片描述
  • 容器只定义了少量(添加删除元素/指向第一个元素)操作。大多数额外操作则由算法库(11章)提供。

2、容器类型的操作集合

  • 标准库为容器类型定义的操作强加了公共的接口。这些容器类型的差别在于它们提供哪些操作,但是如果两个容器提供了相同的操作,则它们的接口(函数名称和参数个数)应该相同。

  • 容器类型的操作集合形成了以下层次结构:

    • 一些操作适用于所有容器类型;

    • 另外一些操作则只适用于顺序或关联容器类型;

    • 还有一些操作只适用于顺序或关联容器类型的一个子集。(关联容器 10章)

3、顺序容器定义

  • 为了定义一个容器类型的对象,必须先包含相关的头文件,即以下头文件之一:
//三种顺序容器的头文件#include<vector>#include<list>#include<deque>
  • 所有容器都是类模板(不是一种数据类型,只是一种类模板,可以用来定义多种数据类型)
vector<string> svec;//空的vector容器,存放string数据类型list<int>  ilist;//空的list容器,存放int数据类型deque<Sale_item> items;//空的deque容器,存放Sale_item数据类型
  • 所有的容器类型都定义了默认构造函数,用于创建指定类型的空容器对象。默认构造函数不带参数。(最常用的)

4、容器元素的初始化

除了默认构造函数,容器类型还提供其他的构造函数,使程序员可以指定元素初值。

这里写图片描述

4.1 将一个容器初始化为另一个容器的副本———直接复制容器,类型必须完全匹配!!!!

vector< int >  iivec(要复制的第一个元素的位置,要复制的最后一个元素的下一个位置);
  • 当不使用默认构造函数,而是用其他构造函数初始化顺序容器时,必须指出该容器有多少个元素,并提供这些元素的初值。同时指定元素个数和初值的一个方法是将新创建的容器初始化为一个同类型的已存在容器的副本:

  • 将一个容器复制给另一个容器时,类型必须匹配:容器类型和元素类型都必须相同!!

vector<int> ivec;vector<int> ivec2(ivec);//可以list<int>  ilist(ivec);//不可以!!!vector类型不同vector<double>  dvec(ivec);//不可以!!!元素类型不同

4.2 初始化为一段元素的副本—-使用迭代器初始化,容器类型不一定要完全相同

  • 尽管不能直接将一种容器内的元素复制给另一种容器,但系统允许通过传递一对迭代器间接实现该功能。

  • 使用迭代器时,不要求容器类型相同,容器内的元素类型也可以不相同,只要相互兼容,能够将要复制的元素转换为所构建的新容器的元素类型,即可实现复制。

  • 迭代器标记了要复制的元素范围,这些元素用于初始化新容器的元素。迭代器标记出要复制的第一个元素和最后一个元素的下一个位置。采用这种初始化形式可复制不能直接复制的容器。更重要的是,可以实现复制其他容器的一个子序列

list<string> slist(svec.begin(),svec.end());//svec是vector<string>类型vector<string>::iterator mid=svec.begin()+svec.end()/2;//找到中间位置deque<string> front(svec.begin(),mid);//初始化front,但是不包括 中间元素(*mid)deque<string> back(mid,svec.end());

我们知道指针就是迭代器,因此允许通过使用内置数组中的一对指针初始化容器也就不奇怪 了

char *words[]={"stately","plump","buck","mulligan"};//定义一个数组size_t words_size = sizeof(words)/sizeof(char *);//数组下标是size_t类型。//这里用了sizeof函数,看 5.8节sizeof操作//sizeof(数组名)=数组内所有元素所占的内存空间//char *words[] 表示的一个数组,里边放的是字符指针,看4.4节。//要求数组里面有多少元素,就使用sizeof(数组名)/sizeof(数组元素类型)//因为数组元素类型是指针,所以sizeof(数组元素类型)=4list<string> word2(words , words+word_size);//定义一个list类型容器,起始位置是数组名(指针)

这里,使用sizeof计算数组的长度,将数组长度加到指向第一个元素的指针上就可以得到指向超出数组末端的下一位置的指针。其中第二个指针提供停止复制的条件,其所指向的位置上存放的元素并没有复制。

4.3 分配和初始化指定数目的元素

  • 创建顺序容器时,可显示指定容器大小和一个(可选的)元素初始化式。容器大小可以是常量或非常量表达式,元素初始化式则必须是可用于初始化其元素类型的对象的值:
const list<int>::size_type list_size =64;//容器的下标是size_type类型list<string>  slist(list_size,"eh?");//共有64个元素,每个都是 "eh?"字符串
  • 创建容器时,除了指定元素个数,还可以选择是否提供元素初始化式。我们也可以只指定容器大小:
list<int> ilist(list_size);//默认初始化,为0extren unsigned get_word_count(const string &file_name);vector<string> svec(get_word_count("Chimera"));
  • 不提供元素初始化式时,标准库将为该容器实现值初始化。采用这种方式必须指定元素个数,默认会初始化,元素类型必须是内置或复合类型,或者是提供了默认构造函数的类类型。如果元素类型没有默认构造函数,则必须显示指定其元素初始化式

  • 接受容器大小做形参的构造函数只适用于顺序容器,而关联容器不支持这种初始化。

0 0
原创粉丝点击