《C++ primer》第五版 第九章 笔记

顺序容器:vector,deque双端队列,list双向链表,forwatd_list单向链表,array,string

顺序容器:根据位置来存储和访问这些元素,顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定。如:

vector   :支持快速随机访问;

list        :支持快速插入/删除;

deque  :双端队列

顺序容器适配器:

stack    :堆栈,先进后出

queue  :队列,先进先出

priority_queue:有优先级管理的队列


迭代器:begin(),end():第一个元素和最后一个元素的后面

容器类型成员:size_type,iterator,const_iterator

需要元素类型,则valud_type,需要元素类型的一个引用,则reference和const_reference

r:返回反向迭代器   c:返回const迭代器

容器的初始化:

C c;   C c1(c2);     C c1=c2;    C c{1,1,1,2……};    C c(b,e)迭代器b和e之间的;   C seq(n);   C seq(n,t);

当将一个容器初始化为另一个容器的拷贝时,两个容器的容器类型和元素类型必须都相同。

赋值:(替换)

seq.assign(b,e);        seg.assign(il);        seq.assign(n,t);

swap:

交换两个相同类型容器的元素,除了array之外,其余的都很快,因为元素本身并没有交换,只是交换了两个容器的内部数据结构。

容器大小:size,max_size,empty

每个容器都支持==和!=,除了无序容器之外,所有容器都支持关系运算符

添加:

push_back,push_front,insert,

http://www.cnblogs.com/ForFreeDom/archive/2012/04/26/2470971.html

    1.每种顺序容器都提供了一组有用的类型定义以及以下操作:a.在容器中添加元素。 b.在容器中删除元素。 c.设置容器大小。 d.(如果有的话)获取容器内的第一个和最后一个元素。

     

      2.容器定义的类型别名:

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

iterator           此容器类型的迭代器类型

const_iterator     元素的只读迭代器类型

reverse_iterator   按逆序寻址元素的迭代器

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

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

value_type           元素类型

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

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

    A.逆序迭代器从后向前遍历容器,并反转了某些相关的迭代器操作:例如,在逆序迭代器上做 ++ 运算将指向容器中的前一个元素。

    B.需要使用元素类型时,只要用 value_type 即可。程序员无须直接知道容器元素的真正类型,就能使用它。如果要引用该类型,则通过reference 和 const_reference 类型实现。

    3.容器的 begin 和 end 操作:

c.begin()   返回一个迭代器,它指向容器 c 的第一个元素

c.end()     返回一个迭代器,它指向容器 c 的最后一个元素的下一位置

c.rbegin()  返回一个逆序迭代器,它指向容器 c 的最后一个元素

c.rend()    返回一个逆序迭代器,它指向容器 c 的第一个元素前面的位置

 

       4.在顺序容器中添加元素:在容器中添加元素时,系统是将元素值复制到容器里。类似地,使用一段元素初始化新容器时,新容器存放的是原始元素的副本。被复制的原始值与新容器中的元素各不相关,此后,容器内元素值发生变化时,被复制的原值不会受到影响,反之亦然。

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

c.push_front(t)             在容器 c 的前端添加值为 t 的元素。返回 void 类型     只适用于 list 和 deque 容器类型.

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

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

c.insert(p,b,e)             在迭代器 p 所指向的元素前面插入由迭代器 b 和 e 标记的范围内的元素,但不包括e本身,e可以是指向最后一个元素的下一个元素的迭代器。返回 void 类型

 

       5.任何 insert 或 push 操作都可能导致迭代器失效。当编写循环将元素插入到 vector 或 deque 容器中时,程序必须确保迭代器在每次循环后都得到更新。避免存储 end 操作返回的迭代器

 

       6.关系操作符:

               A.所有的容器类型都支持用关系操作符来实现两个容器的比较。显比较的容器必须具有相同的容器类型,而且其元素类型也必须相同。

     

               B.容器的比较是基于容器内元素的比较。容器的比较使用了元素类型定义的同一个关系操作符:两个容器做 != 比较使用了其元素类型定义的 != 操作符。如果容器的元素类型不支持某种操作符,则该容器就不能做这种比较运算。

 

               C.如果两个容器具有相同的长度而且所有元素都相等,那么这两个容器就相等;否则,它们就不相等。

  •                 如果两个容器的长度不相同,但较短的容器中所有元素都等于较长容器中对应的元素,则称较短的容器小于另一个容器。

  •                 如果两个容器都不是对文的初始子序列,则它们的比较结果取决于所比较的第一个不相等的元素。

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

 

          7.容器大小的操作:

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

          注意:resize 操作可能会使迭代器失效。在 vector 或 deque 容器上做 resize 操作有可能会使其所有的迭代器都失效。对于所有的容器类型,如果 resize 操作压缩了容器,则指向已删除的元素迭代器失效。

         8.访问元素:

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

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

c[n]        返回下标为 n 的元素的引用。如果 n <0 或 n >= c.size(),则该操作未定义。 只适用于 vector 和 deque 容器

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

              注意:a.使用越界的下标,或调用空容器的 front 或 back 函数,都会导致程序出现严重的错误。

                        b.我们注意到程序员必须保证在指定下标位置上的元素确实存在。下标操作符本身不会做相关的检查。

                        c.如果给出的下标无效,at 函数将会抛出 out_of_range 异常.

       9.删除元素:

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

c.erase(b,e)  删除迭代器 b 和 e 所标记的范围内所有的元素,但不会删除e.回一个迭代器,它指向被删除元素段后面的元素。实际上返回的就是e.果 e 本身就是指向超出末端的下一位置的迭代器,则返回的迭代器也指向容器的超出末端的下一位置

c.clear()     删除容器 c 内的所有元素。返回 void

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

c.pop_front()  删除容器 c 的第一个元素。返回 void。如果 c 为空容器,则该函数未定义.只适用于 list 或 deque 容器

             注意:erase、pop_front 和 pop_back 函数使指向被删除元素的所有迭代器失效。对于 vector 容器,指向删除点后面的元素的迭代器通常也会失效。而对于 deque 容器,如果删除时不包含第一个元素或最后一个元素,那么该 deque 容器相关的所有迭代器都会失效。

 

     10.赋值与 swap:

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

c1.swap(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 的元素

            注意:A.赋值和 assign 操作使左操作数容器的所有迭代器失效。swap 操作则不会使迭代器失效。完成 swap 操作后,尽管被交换的元素已经存放在另一容器中,但迭代器仍然指向相同的元素。

 

                     B.assign 操作首先删除容器中所有的元素,然后将其参数所指定的新元素插入到该容器中。与复制容器元素的构造函数一样,如果两个容器类型相同,其元素类型也相同,就可以使用赋值操作符(=)将一个容器赋值给另一个容器。如果在不同(或相同)类型的容器内,元素类型不相同但是相互兼容,则其赋值运算必须使用 assign 函数。例如,可通过 assign 操作实现将 vector 容器中一段 char* 类型的元素赋给 string 类型 list 容器。

                     C.由于 assign 操作首先删除容器中原来存储的所有元素,因此,传递给 assign 函数的迭代器不能指向调用该函数的容器内的元素。带有一对迭代器参数的 assign 操作允许我们将一个容器的元素赋给另一个不同类型的容器。

 

D.swap 操作实现交换两个容器内所有元素的功能。要交换的容器的类型必须匹配:操作数必须是相同类型的容器,而且所存储的元素类型也必须相同。调用了swap 函数后,右操作数原来存储的元素被存放在左操作数中,反之亦然。

     vector<string> svec1(10); // vector with 10 elements
     vector<string> svec2(24); // vector with 24 elements

vector<string>::iterator itor=svec1.begin(); 
vector<string>::iterator itor2=svec1.end();

    svec1.swap(svec2);
      //执行 swap 后,容器 svec1 中存储 24 个 string 类型的元素,而 svec2 则存储 10 个元素。
          //执行swap后,itor,itor2不失效,而是分别指向svec2中对应的元素

 

七.vector 容器的自增长:

        1.为了使 vector 容器实现快速的内存分配,其实际分配的容量要比当前所需的空间多一些。vector 容器预留了这些额外的存储区,用于存放新添加的元素。于是,不必为每个新元素重新分配容器。所分配的额外内存容量的确切数目因库的实现不同而不同。比起每添加一个新元素就必须重新分配一次容器,这个分配策略带来显著的效率。事实上,其性能非常好,因此在实际应用中,比起 list 和 deque 容器,vector 的增长效率通常会更高。

 

        2.弄清楚容器的 capacity(容量)与 size(长度)的区别非常重要。size 指容器当前拥有的元素个数;而 capacity 则指容器在必须分配新存储空间之前可以存储的元素总数。

        3.vector 容器处理内存分配的细节是其实现的一部分。然而,该实现部分是由 vector 的接口支持的。vector 类提供了两个成员函数:capacity 和reserve 使程序员可与 vector 容器内存分配的实现部分交互工作。capacity 操作获取在容器需要分配更多的存储空间之前能够存储的元素总数,而reserve 操作则告诉 vector 容器应该预留多少个元素的存储空间。

        4.vector 的每种实现都可自由地选择自己的内存分配策略。然而,它们都必须提供 vector 和 capacity 函数,而且必须是到必要时才分配新的内存空间。分配多少内存取决于其实现方式。不同的库采用不同的策略实现。

end指向容器尾部之后的元素,所以,为了获得这个尾元素,必须首先递减此迭代器。

为了删除所有的元素,我们既可以调用clear,也可以用begin和end 获得的迭代器作为参数调用erase

forward_list:单向链表

我们再调用erase和insert之后,都会更新迭代器,因为两者都会使迭代器失效。

string:http://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html

substr操作(pos,n):返回一个strring,包含s中从pos开始的n个字符的拷贝

数制转换:stod,itoa.................................

容器适配器:stack,queue,priority_queue,容器迭代器和函数都有适配器,是一种机制,能够让某种事物的行为看起来像另外一种事物一样。三个顺序容器:stack,queue,priority_queue


标准库提供了三种顺序容器适配器:queue、priority_queue、stack.适配器是标准库中通用的
概念,包括容器适配器、迭代器适配器和函数适配器。本质上,适配器是使一事物的行为类似于另一类事物的行为的一种机制。容器适配器让一种已存在的容器类型采用另一种不同的抽象类型的工作方式实现。例如,stack适配器可使任何一种顺序容器以栈的方式工作,当然你也可以只用容器啊,不使用适配器,这样更灵活

默认的stack和queue都基于deque容器实现,而priority_queue则在vector容器上实现。在创建适
配器时,通过将一个顺序容器指定为适配器的第二个类型实参,可覆盖其关联的基础容器类型:
stack< string, vector<string> > str_stk;
stack< string, vector<string> > str_stk(svec);


对于给定的适配器,其关联的容器必须满足一定的约束条件。stack适配器所关联的基础容器可以是
任何一种顺序容器类型。因此,stack栈可以建立在vector、list、deque容器之上。而queue适配器
要求其关联的基础容器必须提供push_front运算,因此只能建立在list和deque容器上,而不能建立
在vector容器上。priority_queue适配器要求提供随机访问功能,因此可建立vector或deque容器上,
但不能建立在list容器上。












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值