您的位置:首页 > 编程语言 > C语言/C++

顺序容器 - 2【C++ Primer 学习笔记 - 第九章】

2012-10-22 17:16 260 查看
list<int> ilist(10);
// 空容器:*ilist.begin() 无法解引用
// 空容器:back()、front() 操作,未定义
if(!ilist.empty())
{
list<int>::reference val = *ilist.begin();
list<int>::reference val2 = ilist.front();

list<int>::reference last = *--ilist.end();
list<int>::reference last2 = ilist.back();
}


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

c.back()返回容器c 的最后一个元素的引用. c 为空,操作未定义
c.front()返回容器c 的第一个元素的引用. c 为空,操作未定义
c
返回下标为n 的元素的引用

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

只适用于 vector 和 deque 容器
c.at(n)返回下标为 n 的元素的引用。如果下标越界,操作未定义

只适用于 vector 和 deque 容器
at() 成员函数,类似于下标操作,如果下标无效, at 函数会抛出 out_of_range 异常

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

c.erase(p)删除迭代器 p 所指向的元素

返回一个迭代器,指向被删除元素后面的元素。

如果 p 指向最后一个元素,则返回的迭代器指向容器的超出末端的下一位置。

如果 p 指向超出末端的下一位置,则该函数未定义。
c.erase(b, e)删除迭代器b 和 e 所标记的范围内所有的元素

返回一个迭代器,指向被删除元素段 后面的元素.

如果 e 本身就是指向超出末端的下一位置的迭代器,则返回的迭代器也指向超出末端的下一位置
c.clear()删除容器 c 内的所有元素。返回 void 类型
c.pop_back()删除容器 c 内的最后一个元素。返回 void 类型. 如果容器 c 为空,则函数未定义
c.pop_front()删除容器 c 内的第一个元素。返回 void 类型. 如果容器 c 为空,则函数未定义

只适用于 list 或者 deque 容器
#include <algorithm>

list<string> websiteList;
websiteList.push_back("google");
websiteList.push_back("baidu");
websiteList.push_back("taobao");

string searchStr("google");
list<string>::iterator iter = find(websiteList.begin(), websiteList.end(), searchStr);
if(iter!= websiteList.end())
{
websiteList.erase(iter);
}

// 同下:websiteList.erase(websiteList.begin(), websiteList.end());
websiteList.clear();


顺序容器的赋值操作

c1 = c2删除容器 c1 的所有元素,然后将 c2 的元素复制给 c1。 c1 和 c2 的类型必须相同

c1.swap(c2)交换 c1、c2 的内容,调用成功后,c1 存放的是 c2 原来的元素,c2 存放的是 c1 原来的元素

c1 和 c2 的类型必须完全相同。此函数执行速度通常要比,将c2 复制到 c1 的操作快
c.assign(b, e)重设c 的元素,将迭代器 b 和 e 标记的范围内所有的元素复制到c 中。

b、e 必须都不是指向 c 中元素的迭代器。因为该函数是先删除容器中原来存储的所有元素
c.assign(n, t)重设 c , 存储 n 个值为 t 的元素
list<string> slist1;
slist1.push_back("google");
slist1.push_back("baidu");

list<string> slist2;
// 等效于: slist2 = slist1;
// 但是,如果 list<char *> slist1,则,只能使用 assign() 操作
slist2.assign(slist1.begin(), slist1.end());

// 等效于:
// slist1.clear();
// slist1.insert(slist1.begin(), 10, "test");
slist1.assign(10, "test");

// 此操作不会导致迭代器失效
// 如,list<string>::iterator iter = slist1.begin();
// 那么,执行 swap 之后, iter 指向 slist2.begin()
slist1.swap(slist2);


vector 容器,为支持快速的随机访问, vector 容器的元素以连续的方式存放

标准库会以最小的代价来连续存储元素

为了使 vector 容器实现快速的内存分配,其实际分配的容量要比所需的空间多一些。

分配的额外内存容量,因库的不同实现而不同。其性能非常好。

大部分应用下,使用 vector 是最好的

list 容器中,添加一个新元素,标准库只需要创建元素,

然后,将其连接在已经存在的链表中,而不必重新分配内存,也不必复制任何已存在的元素

capacity 和 reserve 成员

vector<int> ivec;
cout << "ivec.size():" << ivec.size() << endl
<< "ivec.capacity():" << ivec.capacity() << endl;
// ivec.size():0
// ivec.capacity():0

for(vector<int>::size_type ix = 0; ix != 15; ++ix)
ivec.push_back(ix);

cout << "ivec.size():" << ivec.size() << endl
<< "ivec.capacity():" << ivec.capacity() << endl;
// ivec.size():15
// ivec.capacity():19

ivec.clear();
ivec.reserve(25);
while(ivec.size() != ivec.capacity())
ivec.push_back(88);

cout << "ivec.size():" << ivec.size() << endl
<< "ivec.capacity():" << ivec.capacity() << endl;
// ivec.size():25
// ivec.capacity():25

ivec.push_back(99);
cout << "ivec.size():" << ivec.size() << endl
<< "ivec.capacity():" << ivec.capacity() << endl;
// ivec.size():26
// ivec.capacity():37


容器的选用

vector 和 deque 都支持快速随机访问,

vector ,执行插入和删除操作时,如果不是容器末尾进行操作,那么它的开销较大

deque 容器,双端队列,在容器首、尾 的插入和删除操作都非常快。

deque 容器中,首、尾,插入元素操作,不会使任何迭代器失效

而在首、尾 删除元素,则会使指向被删除元素的迭代器失效。

任何其他位置的插入、删除,会使指向该容器元素的所有迭代器失效。

list 容器可以在任意位置实现快速的插入和删除,但是,随机访问的开销较大

list 容器表示不连续的内存区域,允许向前或向后逐个遍历元素,

访问 list 容器中的某个元素,需要遍历相关的所有其他元素

在 list 容器的元素之间移动的唯一方法是顺序跟随指针,

比如,从5号元素,移动到15号元素,必须遍历5-15之间的所有元素
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: