Sequentials Containers

来源:互联网 发布:有淘宝优惠券的app叫啥 编辑:程序博客网 时间:2024/05/21 10:19

Sequential Containers 

顺序容器

 From C++ Primer fourth edition

author wcdj 2010-3-12 Arbor Day

容器是容纳特定类型对象的集合。vector类型是一种顺序容器sequential container),它将单一类型元素聚集起来成为容器,然后根据位置来存储和访问这些元素。顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定。

标准库定义了三种顺序容器类型:vectorlistdequedouble-ended queue双端队列)。它们的差别在于:访问元素的方式,以及添加或删除元素相关操作的运行代价。

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

顺序容器类型

顺序容器

vector

支持快速随机访问

list

支持快速插入、删除

deque

双端队列

顺序容器适配器

stack

后进先出(LIFO)

queue

先进先出(FIFO)队列

priority_queue

有优先级管理的队列

容器只定义了少量的操作,大多数额外操作由算法库提供。

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

l         一些操作适合于所有容器类型。

l         另外一些操作只适合于顺序或关联容器类型。

l         还有一些操作只适合于顺序或关联容器类型的一个子集。

 

u       顺序容器的定义

为了定义一个顺序容器类型的对象,必须先包含下列头文件之一:

#include <vector>

#include <list>

#include <deque>

所有的容器都是类模板。要定义某种特殊的容器,必须在容器名后加一对尖括号,尖括号里面提供容器中存放的元素的类型

vector<string>   svec;             // empty vector that can hold strings

list<int>   ilist;                      // empty list that can hold ints

deque<Sales_item>   items;    // empty deque that holds Sales_items

所有的容器类型都定义了默认构造函数,用于创建制定类型的空容器对象

 

u       (顺序)容器元素的初始化

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

容器构造函数

C<T> c;

创建一个名为c的空容器。C是容器类型名,如vectorT是元素类型,如intstring

C c(c2);

创建容器c2的副本ccc2必须具有相同的容器类型,并存放相同类型的元素。适用于所有容器。

C c(b,e);

创建c,其元素是迭代器be标示的范围内元素的副本。适用于所有容器。

C c(n,t);

n个值为t的元素创建容器c,其中值t必须是容器类型C的元素类型的值,或者是可转换为该类型的值。

只适用于顺序容器

C c(n);

创建有n个值初始化(value-initialized)元素的容器c

只适用于顺序容器

1)         将一个容器初始化为另一个容器的副本

当不使用默认构造函数,而是用其他构造函数初始化顺序容器时,必须指出该容器有多少个元素,并提供这些元素的初值。同时指定元素个数和初值的一个方法是将新创建的容器初始化为一个同类型的已存在容器的副本。

vector<int> ivec;

vector<int> ivec2(ivec);       // ok: ivec is vector<int>

list<int> ilist(ivec);            // error: ivec is not list<int>

vector<double> dvec(ivec);  // error: ivec holds int not double

    注意:将一个容器复制给另一个容器时,类型必须匹配:容器类型元素类型都必须相同。

2)         初始化为一段元素的副本

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

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

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

    // initialize slist with copy of each element of svec

    list<string> slist( svec.begin() , svec.end());

    

    // find midpoint in the vector

    vector<string>::iterator mid=svec.begin()+svec.size()/2;

    // initialize front with first half of svec: The elements up to but not including *mid

    deque<string> front(svec.begin() , mid);

    // initialize back with second half of svec: The elements *mid through end of svec

    deque<string> back(mid , svec.end());

    注意:指针就是迭代器,因此允许通过使用内置数组中的一对指针初始化容器:

    char *words[]={“my”,”name”,”is”,”wcdj”};

    // calculate how many elements in words

    size_t words_size=sizeof(words)/sizeof(char *);

    // use entire array to initialize words2

list<string> words2(words , words+words_size);

说明:使用sizeof计算数组的长度。

3)         分配和初始化指定数目的元素(只适用于顺序容器)

创建顺序容器时,可显示指定容器大小一个(可选的)元素初始化式。容器大小可以是常量或非常量表达式,元素初始化式则必须是可用于初始化其元素类型的对象的值:

const list<int>::size_type list_size=64;

list<string> slist(list_size , “wcdj”);   // 64 strings, each is wcdj

说明:slist含有64个元素,每个元素都被初始化为”wcdj”字符串。

 

list<int> ilist(list_size);   // 64 elements, each initialized to 0

// svec has as many elements as the return value from get_word_count

extern unsigned get_word_count(const string &file_name);

vector<string> svec(get_word_count(“wcdj”));

说明:不提供元素初始化式时,标准库将为该容器实现值初始化。采用这种类型的初始化,元素类型必须是内置复合类型,或者是提供了默认构造函数的类类型。如果元素类型没有默认构造函数,则必须显示指定其元素初始化式。

 

u       容器内元素的类型约束

C++语言中,大多数类型都可用作容器的元素类型。容器元素类型必须满足以下两个约束:

(1) 元素类型必须支持赋值运算。

(2) 元素类型的对象必须可以复制

 

u       容器适配器

除了顺序容器,标准库还提供了三种顺序容器适配器:queuepriority_queuestack

适配器(adaptor)是标准库中通用的概念,包括容器适配器迭代器适配器函数适配器

本质上,适配器是使一事物的行为类似于另一事物的行为的一种机制。

容器适配器让一种已存在的容器类型采用另一种不同的抽象类型的工作方式实现。例如,stack()适配器可使任何一种顺序容器以栈的方式工作。下表列出了所有容器适配器通用的操作和类型。

Common Adaptor Operations and Types(适配器通用的操作和类型)

size_type

一种类型,足以存储此适配器类型最大对象的长度

value_type

Element type.(元素类型)

container_type

基础容器的类型,适配器在此容器类型上实现

A a;

Create a new empty adaptor named a.

A a(c);

Create a new adaptor named a with a copy of the container c.

Relational Operators(关系操作符)

所有适配器都支持全部关系操作符:== != < <= > >=

To use an adaptor, we must include its associated header:

#include <stack> // stack adaptor

#include <queue> // both queue and priority_queue adaptors

适配器的初始化

Each adaptor defines two constructors: the default constructor that creates an empty object and a constructor that takes a container and makes a copy of that container as its underlying value. For example, assuming that deq is a deque<int>, we could use deq to initialize a new stack as follows:

stack<int> stk(deq); // copies elements from deq into stk


原创粉丝点击