C++ Primer(顺序容器 上)

来源:互联网 发布:阳西网络问政最新消息 编辑:程序博客网 时间:2024/05/17 22:19

第九章 顺序容器

标准库定义了三种顺序容器类型:vector、list 和 deque。

标准库还提供了三种容器适配器(adaptors): stack, queue, priority_queue

9.1顺序容器的定义:

#include <vector>        

vector<string> svec;    

#include <list>          

list<int> ilist;      

#include <deque>         

deque<Sales_item> items; 

9.1.1容器元素的初始化

9-2 容器构造函数

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>类型,

vector<int> ivec2(ivec);  //复制初始化

vector ivec2(ivec);  //  同上

vector<int> ivec(10);   //  十个零

vector<int>ivec(10,1);   //十个一

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

vector<int> ivec(vec.begin(),vec.end())   //用两个迭代器复制初始化

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

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

list<string> slist(list_size,"ee");   //64个字符串,每个都是ee

9.1.2 容器内元素的类型约束

容器内的元素类型必须是  1)支持赋值运算,2)支持复制

除了引用类型外,所有内置和复合类型都可以做元素类型。

容器的容器

vector< vector<int> .> lines;  //  attention!!!!这里> .> 之间必须有空格!!

9.2迭代器和迭代器范围

所有标准库容器都支持*iter,iter->mem,++iter,iter++,--iter,iter--,iter1==iter2,iter1!=iter2

vectordeque提供了额外的运算!!iter+niter-niter1+=iter2>,<,>=,<=.

list容器的迭代器既不支持算术运算(加法或减法),也不支持关系运算(<=,<,>=,>),只提供前置或后置的自增,自减运算及相等(不等)运算。

9.2.1迭代器范围

C++ 语言使用一对迭代器标记迭代器范围(iterator range),这两个迭代器分别指向同一个容器中的两个元素或超出末端的下一位置,通常将它们命名为

first 和 last,或 beg 和 end,用于标记容器中的一段元素范围。

此类元素范围称为左闭合区间(left-inclusive interval),其标准表示方式为: [ first, last )

迭代器first和last形成一个迭代器范围需满足一下条件:它们指向同一个容器中的两个元素或超出末端的下一位置;last绝对不能位于first之前。

9.2.2使迭代器失效的容器操作

使用迭代器的时候,一定要注意那些操作可以使迭代器失效!!只要有元素的添加和删除,begin或者end的结果会失效!!最好载重新定值。

9.3顺序容器的操作

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

9.3.1容器定义的类型别名

9-5 容器定义的类型别名

size_type

无符号整型,足以存储此容器类型的最大可能容器长度

iterator

此容器类型的迭代器类型

const_iterator

元素的只读迭代器类型

reverse_iterator

按逆序寻址元素的迭代器

const_reverse_iterator

元素的只读(不能写)逆序迭代器

difference_type

足够存储两个迭代器差值的有符号整型,可为负数

value_type

元素类型

reference

元素的左值类型,是value_type&的同义词

const_reference

元素的常量左值类型,等效于const value_type&

9.3.2 begin和end成员

返回一个迭代器c.begin() c.end()

返回一个逆序迭代器 c.rbegin() c.rend()

容器是const,返回类型要加上const_前缀

9.3.3 在容器中添加元素

9-7 在顺序容器中添加元素的操作

c.push_back(t)

在容器c的尾部添加值为t的元素。返回void类型

c.push_front(t)

在容器c的前端添加值为t的元素。返回void类型

只适用于listdeque容器类型

c.insert(p,t)

在迭代器p所指向的元素前面插入值为t的新元素。返回指向新添加元素的迭代器。

c.insert(p, n, t)

在迭代器p所指向的元素前面插入n个值为t的新元素。返回void类型

c.insert(p, b, e)

在迭代器p所指向的元素前面插入由迭代器be标记的范围内的元素。返回void类型

1.在容器的指定位置添加元素

新元素的插入在迭代器指向的位置之前

list<string> lst;

list<string>::iterator iter=lst.begin();

while(cin>>word)

iter=lst.insert(iter,wrod);//  同push_front功能相同

2.不要存储end操作返回的迭代器,可以在每次做完插入运算后重新计算end迭代器值:

while(first!=v.end()){

first=v.insert(first,42);

++first;

}

9.3.4关系操作符

两个容器可以大小比较,其实是其元素在作比较,如果元素不支持,则容器也不支持

ivec1 < ivec2

要求完全匹配,即容器类型与元素类型都相同,且元素类型支持<操作

9.3.5容器大小的操作

9-8 顺序容器的大小操作

c.size()

返回容器c中的元素个数。返回类型为c::size_type

c.max_size()

返回容器c可容纳的最多元素个数。返回类型为c::size_type

c.empty()

返回标记容器大小是否为0的布尔值

c.resize(n)

调整容器c的长度大小,使其能容纳n个元素

如果n<c.size(), 则删除多出来的元素; 否则,添加采用值初始化的新元素

c.resize(n, t)

调整容器c的大小,使其能容纳n个元素。所有新添加的元素之都为t

9.3.6访问元素

9-9 访问顺序容器内元素的操作

c.back()

返回容器c的最后一个元素的引用。如果c为空,则该操作未定义

c.front()

返回容器c的第一个元素的引用。如果c为空,则该操作未定义

c[n]

返回下标为n的元素的引用

如果n<0n>=c.size(),则该操作未定义

只适用于vectordeque容器

c.at(n)

返回下表为n的元素的引用。如果下标越界,则该操作未定义

只适用于vectordeque容器

9.3.7删除元素

9-10 删除顺序容器内元素的操作

c.erase(p)

删除迭代器p所指向的元素

返回一个迭代器,它指向被删除元素后面的元素。如果p指向容器内的最后一个元素,则返回的迭代器指向容器的超出末端的下一位置。如果p本身就是指向超出末端的下一位置的迭代器,则该函数未定义

c.erase(b, e)

删除迭代器be所标记的范围内的所有元素

返回一个迭代器,它指向被删除元素段后面的元素。如果e本身就是指向超出末端的下一位置的迭代器,则返回的迭代器也指向容器的超出末端的下一位置

c.clear()

删除容器c内的所有元素。返回void

c.pop_back()

删除容器c的最后一个元素。返回void。如果c为空容器,则该函数未定义

c.pop_front()

删除容器c的第一个元素。返回void。如果c为空容器,则该函数未定义。只适用于listdeque容器

1.删除第一个或最后一个元素

vector容器类型不支持pop_front操作。

pop_front操作通常与front操作配套使用

while(!ilist.empty()){

process(ilist.front());

ilist.pop_front();

}//使用front获取要处理的元素,使用pop_front从容器list删除该元素。

2.删除一个元素

必须在容器中找到要删除的元素后,才能使用erase操作,且必须保证迭代器不是end迭代器

string searchValue("quasimodo");

list<string>::iterator iter=find(slist.begin(),slist.end(),searchValue);

if(iter!=slist.end())

slist.erase(iter);

9.3.8赋值与swap

9-11 顺序容器的赋值操作

c1 = c2

删除容器c1的所有元素,然后将c2的元素复制给c1c1c2的类型(包括容器类型和元素类型)必须相同

c1.swap(c2)

交换内容:调用完该函数后,c1中存放的是c2原来的元素,c2中存放的则是c1原来的元素。c1c2的类型必须相同。该函数的执行速度通常要比将c2的元素复制到c1的操作快

c.assign(b, e)

重新设置c的元素:将迭代器be标记的范围内所有的元素复制到c中。be必须不是指向c中元素的迭代器

c.assign(n, t)

将容器c重新设置为存储n个值为t的元素

1.使用assign

assign首先删除容器中的所有元素,然后将其参数所指定的新元素插入到该容器中。两个容器类型相同,元素类型相同,可以使用赋值操作符(=)。

在不同(或相同)类型的容器内,元素类型不同但是相互兼容,赋值运算必须使用assign函数。

2.使用swap操作节省删除元素的成本

要交换的容器类型匹配,操作数必须是相同类型的容器,而且所存储的元素类型也必须相同。

9.4vector容器的自增长

vector提供两个成员函数:capacity和reserve。capacity操作获取容器需要分配更多的存储空间之前能够存储的元素总数,reserve操作则告诉vector容器应该预留多少个元素的存储空间。

size指的是容器当前拥有的元素个数。

9.5容器的选用

list容器可以高效的insert和erase一个元素且不需要移动任何其他元素,但不支持随机访问。

vector在除尾部的其他任何位置插入或删除操作都要移动这个元素右边的所有元素。

deque容器在两端插入和删除快,在中间操作代价高。

通常vector是随机访问的最佳选择。























0 0
原创粉丝点击