C++ Primer知识点学习(二)

原创 2018年04月16日 20:26:21
第二部分
1、顺序容器
【顺序容器:】
vector:支持快速随机访问。但在容器的任意位置插入或删除元素,比在容器尾部插入和删除的开销更大。
list:支持快速插入/删除。随机访问开销较大
deque:双端队列。与vector类似,但支持在容器的首部快速插入新元素,而且无论在哪一端插入或删除都不会引起元素的重新定位。  

【容器的选择】
通常,除非找到选择使用其他容器的更好理由,否则vector容器都是最佳选择。

使用【vector<pair<float, float>> ,并配合sort()函数】可以实现键值对的存储排序。

【顺序容器适配器:
stack:后进先出(LIFO)栈     所关联的基础容器可以是任意一种顺序容器类型
queue:先进先出(FIFO)队列  要求其关联的基础容器必须提供push_front运算,因此只能建立在list容器上,而不能建立在vector容器上
priority_queue:有优先级管理的队列   允许用户为队列中存储的元素设置优先级,根据指定的优先级级别插入  要求提供随机访问功能,因此可以建立在vector或deque容器上,但不能建立在list容器上。
默认的stack和queue都基于deque容器实现,而priority_queue则在vector容器上实现。

适配器是使一事物的行为类似于另一事物的行为的一种机制。所有的适配器都会在其基础顺序容器上定义一个新的接口
相关头文件:stack、queue

将一个容器复制给另外一个容器时,类型必须匹配:容器和元素类型都必须相同。
使用迭代器时,不要求容器类型相同。容器内的元素也可以不同,只要能够互相兼容,能够将要复制的元素转换为所构建的新容器的元素类型,即可实现复制。迭代器标出要复制的第一个元素和最后一个元素。
容器元素类型必须满足以下两个约束:
1、元素类型必须支持赋值运算
2、元素类型的对象必须可以复制
IO库类型不支持复制或赋值。因此,不能创建存放IO类型对象的容器。
在指定容器元素为容器类型时,必须如下使用空格:vector < vector<string> > lines;

Tips
1、迭代器运算(iter ± n、iter1 ±= iter2、iter1 - iter2)以及迭代器的关系操作符(>、>=、<、<=)只适用于vector和deque迭代器
2、在容器中添加元素时,系统是将元素值复制到容器里。
3、任何insert或push操作都可能导致迭代器失效。当编写循环将元素插入到vector或deque容器中时,程序必须确保迭代器在每次循环后都得到更新。特别地,不要存储end操作返回的迭代器,添加或删除deque或vector容器内的元素都会导致存储的迭代器失效。
4、c[n]和c.at(n)只适用于vector和deque容器  【快速随机访问特征】
5、swap操作不会删除或插入任何元素,而且保证在常量时间内实现交换。迭代器不会失效,仍然指向同一元素,只是这些元素被存储在不同的容器之中。
6、vector容器的元素以连续方式存放,capacity()操作获取在容器需要分配更多的存储空间之前能够存储的元素总数。reserve()操作告诉vector容器应预留多少个元素的存储空间。
7、string类型在使用只有一个指针参数的构造函数时,该指针指向以空字符结束的字符数组中的一个元素。
begin:返回一个迭代器,指向容器的第一个元素
end:返回一个迭代器,指向容器最后一个元素的下一位置
back:返回容器的最后一个元素的引用
front:返回容器的第一个元素的引用

【string类型:字符容器】
只适用于string类型的操作
1、substr函数 //子串操作
2、append和replace函数//append函数指字符添加在string对象的末尾;replace函数将字符插入到指定位置,从而替换string对象中一段已存在的字符,等效于调用erase和insert函数。
3、一系列find函数//find、rfind、find_first_of、find_last_of、find_first_not_of、find_last_not_of、
4、string对象的比较compare
5、assign、swap、insert、push_back、begin、end、下标等操作均适用

2、关联容器
//一个键对应一个元素
map:以键-值对的形式组织,元素通过键来存储和读取【适用于需要存储或修改每个键所关联的值的情况
set:仅包含一个键,并有效地支持关于某个键是否存在的查询。大小可变的集合,支持通过键实现的快速读取。【有效地存储不同值的集合
//一个键可以对应多个元素
multimap:支持同一个键多次出现的map类型
multiset:支持同一个键多次出现的set类型
【pair类型】
与容器一样,pair类型也是一种模板类型。但与之前介绍的容器不同,在创建pair对象时,必须提供两个类型名。
pair类型使用相当繁琐,因此,如果需要定义多个相同的pair类型对象,可以考虑利用typedef简化其声明。
pair对象具有first、second两个公有成员。
对于map容器,value_type并非元素的类型,而是描述其关联值类型的pair类型。
pair类型在key(first)相等的情况下,比较两者的value(second)。

【map】
所有的比较函数必须在键类型上定义严格弱排序,所谓的严格弱排序可理解为键类型数据上的“小于”关系。对于键类型,唯一的约束就是必须支持<操作符,至于是否支持其它的关系或相等运算,则不作要求。【为了实现快速查找,map内部本身就是按序存储的(比如红黑树)。在插入<key, value>键值对时,就会按照key的大小顺序进行存储。这也是作为key的类型必须能够进行<运算比较的原因】
【map<类型1,类型2,自定义比较函数>】
value_type是存储元素的键以及值的pair类型,而且键为const。对迭代器解引用时获得一个引用,指向容器中一个value_type类型的值,该值包含const key_type(键)和mapped_type(值)类型成员的pair对象。
用下标(键)访问map对象时,如果该键值不存在将导致在map容器中添加一个新的元素,它的键即为该下标值。该运算生成mapped_type类型的值。//【该特性可以用来统计字符串中出现字符的个数】
使用make_pair或typedef简化实参传递。
如果试图插入的元素所对应的键已存在容器中,则insert将不做任何操作。
对于map对象,count成员的返回值只能是0或1,可以简单判断该值是否存在。因为map容器只允许一个键对应一个实例,所以count可有效地表明一个键是否存在。
【set】
键的集合。不支持下标操作,没有mapped_type类型,value_type不是pair类型,而是与key_type相同的类型,也就是set中存储的元素类型。与map一样,其键必须唯一,并且不能修改。
set集合容器使用一种称为红黑树(Red-Black Tree) 的平衡二叉检索树的数据结构,来组织泛化的元素数据。每个节点包含一个取值红色或黑色的颜色域,以利于进行树的平衡处理。作为节点键值的元素的插入,必须确保每个子树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值。不会将重复的键值插入容器,也不需要指定具体的插入位置,而按元素在树中的关联关系,进行位置检索和插入,元素的删除亦然。
 元素数据的检索,使用的是二叉检索树的中序遍历算法,检索的效率高于vector、 deque和list等容器。由于采用中序遍历算法可将二叉检索树的键值,由小到大排列遍历出来,因此 set 集合容器蕴含了元素间的有序性


【multimap和multiset】
允许一个键对应多个实例。所支持的操作与map和set相同,但不能支持下标运算。
在multimap中,同一个键所关联的元素必然相邻存放。
查找元素:find和count操作;lower_bound(k)【返回键不小于k的第一个元素】和upper_bound(k)【返回键大于k的第一个元素】【 该操作适用于所有关联容器,但更常用于multimap和multiset,若该键存在,则返回两个不同的迭代器,lower_bound返回的迭代器指向该键关联的第一个实例,而upper_bound返回的迭代器则指向最后一个实例的下一位置。若键不存在,则两者返回同一迭代器】。
equal_range(k)//返回一个迭代器的pair对象。first成员等价于lower_bound(k)返回的迭代器,second成员等价于up_bound(k)返回的迭代器

//*******************************************在基础知识中有容器与迭代器相关内容*******************************************************************

3、泛型算法
泛型:可以操作在多种容器类型上。算法:实现共同的操作。
泛型算法本身从不执行容器操作,只是单独依赖迭代器和迭代器操作实现。
头文件:algorithm【泛型算法】、numeric【算术算法】
【只读算法】
find()
accumulate()//返回类型是第三个实参的类型
find_first_of()
【写容器元素的算法】
fill()
fill_n()
back_inserter()//迭代器适配器,头文件iterator,能在容器中添加一个新元素
copy()
replace()
replace_copy()
【排序算法】
去除重复
sort()//排序,针对序列容器。
unique()//“删除”相邻的重复运算。重新排列输入范围内的元素,并返回一个迭代器,表示无重复的值范围的结束。
erase()//删除容器项
stable_sort()//对于长度相同的元素,将保留其字典顺序。
count_if()//返回使谓词函数返回条件成立的元素个数。
set_intersection()//查找两个查询中的公共行

谓词:做某些检测的函数,返回用于条件判断的类型,指出条件是否成立。其返回类型可转换为bool值的函数
算法不直接修改容器的大小。如果需要添加或删除元素,则必须使用容器操作。

【插入迭代器】
与容器绑定在一起。
back_inserter:创建使用push_pack实现插入的迭代器。
front_inserter:使用push_front实现插入//vector没有push_front操作,所以不能使用front_inserter
inserter:使用insert实现插入操作,在所标明的位置前面插入新元素。
【iostream迭代器】
可以输入或输出流绑定在一起。
istream_iterator:可比较。
ostream_iterator:不可比较。一旦赋值,没有办法再改变这个值,每个不同的值都只能正好输出一次。没有->操作
【反向迭代器】
从最后一个到第一个元素遍历容器。rbegin()、rend()、reverse_iterator
流迭代器不能创建反向迭代器。
【const迭代器】
const_iterator:不希望使用该迭代器来修改容器中的元素。
【五种迭代器】
算法要求的迭代器操作分类:
1、输入迭代器
不能写,只支持自增运算。
2、输出迭代器
不能读,只支持自增运算。对于指定的迭代器值应该使用一次*运算,而且只能用一次。
3、前向迭代器
读和写,只支持自增运算。
4、双向迭代器
读和写,支持自增和自减运算。
5、随机访问迭代器
读和写,支持完整的迭代器算术运算。

map、set和list类型提供双向迭代器,而string、vector、deque容器上定义的迭代器都是随机访问迭代器,用作访问内置数组元素的指针也是随机访问迭代器。istream_iterator是输入迭代器。ostream_iterator是输出迭代器。关联容器只能使用算法的一个子集,因为关联容器的键是const对象。因而不能使用任何写序列元素的算法。

【泛型算法的结构】
根据对元素的操作将算法分为:
1、只读算法,不改变元素的值和顺序
2、给指定元素赋新值的算法
3、将一个元素的值移给另一个元素的算法
【算法所带的形参定义的算法模式】
alg(beg,end,other parms);
alg(beg,end,dest,other parms);//带有单个目标迭代器,通常配合使用插入迭代器或者ostream_iterator,防止出现输出容量不足问题。
alg(beg,end,beg2,other parms);//与写入dest的算法一样,只带有beg2的算法也假定以beg2开始的序列与beg和end标记的序列一样大。
alg(beg,end,beg2,end2,other parms);//指定第二个输入范围
【通过两种函数命名和重载的规范定义的算法模式】
1、测试输入范围内元素的算法
这些算法通常用到标准关系操作符:==或<,其中大部分允许程序员提供比较或测试函数取代操作符的使用,即使用谓词函数作为额外的参数
带有谓词函数形参的算法,其名字带有后缀_if,防止重载版本可能导致的二义性,以及可使得元素采取不同操作符运算
2、应用于对输入范围内元素重新排序的算法
标准库可提供将重新排列输入范围的元素写到指定的输出目标。此版本的算法在名字中添加了_copy后缀。将修改过的元素写到输出序列,而不是写回输入范围。
【容器特有的算法】
list容器特有的操作。对于list对象,应该首先使用list容器
特有的成员版本,而不是泛型算法。
remove和unique的list版本修改了其关联的基础容器,真正删除了指定的元素。
merge和splice运算会破坏它们的实参。

微信WEB开发知识点手册

-
  • 1970年01月01日 08:00

C++ Primer 知识点总结

第一章 1.1 编写简单的C++程序 每个C++程序都包含一个或多个函数,而且必须有一个命名为main。main函数是唯一被操作系统显示调用的函数。 返回0说明程序成功执行完毕。 定义函数必须指定4个...
  • linyk3
  • linyk3
  • 2015-08-06 21:21:30
  • 281

C++ Primer 学习笔记(持续更新......)

本笔记主要是一个记录,整理和总结一下C++学习过程中的知识点。 struct和class 区别:两个关键字都是进行类的定义。struct也可以定义类,和class定义的类唯一不同之处就在于默认的初始访...
  • u012931582
  • u012931582
  • 2017-03-12 22:05:04
  • 1198

如何利用《C++ Primer》学习C++?

《C++ Primer》作为久负盛名的C++经典教程,丰富的教学辅助内容、精心组织的编程示范,无论是初学者入门,或是中、高级程序员提升,都是不容置疑的首选。一本好书只有读过才有价值,然而《C++ Pr...
  • shiyanlou_chenshi
  • shiyanlou_chenshi
  • 2015-08-14 16:00:14
  • 1504

C++ primer中知识点小结(一)

之前看完了c++ primer,由于涉及到的知识点挺多的,只好边看边做些笔记,进行总结,方便日后复习。 1.关于迭代器          const_iterator和const的iterator...
  • renyp8799
  • renyp8799
  • 2014-10-10 18:59:47
  • 579

c++ primer 的学习心得

          学习《c++  primer 3rd 中文版》有一个多月了,没有按顺序看,因为以前看过 钱能的 那本 《c++程序设计》,就从网上下了电子版的看,pdf的,可以在上面直接做笔记,有...
  • fengfengxxx
  • fengfengxxx
  • 2006-04-04 21:19:00
  • 1089

如何学习C++ primer 第五版

作者:dawnmist 链接:http://www.zhihu.com/question/32087709/answer/54936403 来源:知乎 著作权归作者所有,转载请联系作者获得授权。...
  • w3071206219
  • w3071206219
  • 2016-08-22 22:03:22
  • 1061

《C++primer(第五版)》学习之路-第七章:类

【 声明:版权所有,转载请标明出处,请勿用于商业用途。  联系信箱:libin493073668@sina.com】   7.1 定义抽象数据类型   1.类的基本思想是数据抽象和封装,数据抽...
  • libin1105
  • libin1105
  • 2015-09-22 23:01:02
  • 2301

《C++ Primer》第五版中文版学习笔记

  • 2015年03月05日 10:58
  • 1.4MB
  • 下载

如何正确的通过 C++ Primer 学习 C++?(转自知乎)

如何正确的通过 C++ Primer 学习 C++?(转自知乎) 作者:dawnmist 链接:https://www.zhihu.com/question/32087709/answer/549...
  • james_616
  • james_616
  • 2018-03-02 10:43:18
  • 179
收藏助手
不良信息举报
您举报文章:C++ Primer知识点学习(二)
举报原因:
原因补充:

(最多只允许输入30个字)