• C++高级编程

    针对C++泛型编程STL,探讨C++更深层的使用。

    1. 模板

    1.1 模板的概念

    模板就是建立通用的模具,大大提高复用性

    模板的特点:

    泛型编程主要就是利用模板,C++提供两种模板,函数模板类模板

    1.2 函数模板

    1.2.1 函数模板的语法

    函数模板作用:

    建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。

    语法:

    解释:

    template:声明创建模板

    typename:表明其后面的符号是一种数据类型,可以用class代替

    T:通用的数据类型,名称可以替换,通常为大写字母

    示例如下:

    总结:

    1.2.2 函数模板注意事项

    注意事项:

    示例如下:

    总结:使用模板时必须确定出通用数据类型T,并且能够推导出一致的类型。

    1.2.3 函数模板的案例

    案例描述:

    示例如下:

    总结:模板可以提高代码复用,需要熟练掌握

    1.2.4 普通函数与函数模板的区别

    普通函数与函数模板区别:

    示例如下:

    总结:建议使用显示指定类型的方式,调用函数模板,因为可以自己确定通用类型T。

    1.2.5 普通函数与函数模板的调用规则

    调用规则如下:

    1. 如果函数模板和普通函数都可以实现,优先调用普通函数
    2. 可以通过空模板参数列表来强制调用函数模板
    3. 函数模板也可以发生重载
    4. 如果函数模板可以产生更好的匹配,优先调用函数模板

    示例如下:

    总结:既然提供了函数模板,最好就不要提供普通函数,否则容易出现二义性。

    1.2.6 模板的局限性

    局限性:模板的通用性并不是万能的。

    例如:

    在上述代码中提供的赋值操作,如果传入的a和b是一个数组,就无法实现了。

    再例如:

    在上述代码中,如果T的数据类型传入的是像Person这样的自定义数据类型,也无法正常运行。

    因此C++为了解决这种问题,提供模板的具体化,可以为这些特定的类型提供具体化的模板

    示例如下:

    总结:

    1.3 类模板

    1.3.1 类模板语法

    类模板作用:建立一个通用类,类中的成员数据类型可以不具体指定,用一个虚拟的类型来代表。

    语法:

    解释:

    template:声明创建模板

    typename:表面其后面的符号是一种数据类型,可以用class代替

    T:通用的数据类型,名称可以替换,通常为大写字母

    示例如下:

    总结:类模板和函数模板语法相似,在声明模板template后面加类,此类称为类模板。

    1.3.2 类模板与函数模板区别

    类模板与函数模板区别主要有两点:

    1. 类模板没有自动类型推导的使用方式
    2. 类模板在模板参数列表中可以有默认参数

    示例如下:

    总结:

    1.3.3 类模板中成员函数创建时机

    类模板中成员函数和普通类中成员函数创建时机是有区别的:

    示例如下:

    总结:类模板中的成员函数并不是一开始就创建的,在调用时才去创建。

    1.3.4 类模板对象做函数参数

    类模板实例化出的对象,向函数传参的方式,一共有三种传入方式:

    1. 指定传入的类型 直接显示对象的数据类型
    2. 参数模板化 将对象中的参数变为模板进行传递
    3. 整个类模板化 将这个对象类型模板化进行传递

    示例如下:

    总结:

    1.3.5 类模板与继承

    当类模板碰到继承时,需要注意以下几点:

    示例如下:

    总结:如果父类是类模板,子类需要指定出父类中T的数据类型。

    1.3.6 类模板成员函数类外实现

    示例如下:

    总结:类模板中成员函数类外实现时,需要加上模板参数列表。

    1.3.7 类模板分文件编写

    将声明和实现写到同一个文件中,并更改后缀名为.hpp,hpp是约定的名称,并不是强制。

    示例如下:

    person.hpp中代码:

    主函数.cpp中代码

    1.3.8 类模板与友元

    全局函数类内实现:直接在类内声明友元并写出全局函数的实现

    全局函数类外实现:需要提前让编译器知道全局函数的存在,并且全局函数用到了类模板参数,还得让这个全局函数知道有这么个类模板。

    示例如下:

    全局函数类内实现

    全局函数类外实现

    总结:建议全局函数做类内实现,用法简单,而且编译器可以直接识别。

    1.3.9 类模板案例(案例比较综合,含金量比较高)

    案例描述: 实现一个通用的数组类,要求如下:

    示例如下:

    myArray.hpp中代码

     

    类模板案例—数组类封装.cpp中

    总结:能够利用所学知识点实现通用的数组,这个案例综合性较强,涉及到核心编程部分的构造(普通构造和拷贝构造)、析构、运算符重载(=和[ ])以及高级编程部分的类模板。在拷贝构造和=运算符重载的过程中要注意深拷贝,防止堆区内存重复释放。

    2.STL初识

    2.1 STL的诞生

    2.2 STL基本概念

    2.3 STL六大组件

    STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器

    1. 容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据。
    2. 算法:各种常用的算法,如sort、find、copy、for_each等
    3. 迭代器:扮演了容器与算法之间的胶合剂
    4. 仿函数:行为类似函数,可作为算法的某种策略。
    5. 适配器:一种用来修饰容器或者仿函数或迭代器接口的东西。
    6. 空间配置器:负责空间的配置与管理。

    2.4 STL中容器、算法、迭代器

    容器:置物之所也

    STL容器就是将运用最广泛的一些数据结构实现出来

    常用的数据结构:数组、链表、树、栈、队列、集合、映射表等

    这些容器分为序列式容器关联式容器两种:

    序列式容器:强调值的排序,序列式容器中的每个元素均有固定的位置。 关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系。

     

    算法:问题之解法也

    有限的步骤,解决逻辑或数学上的问题,这一门学科我们叫做算法(Algorithms)

    算法分为:质变算法非质变算法

    质变算法:是指运算过程中会更改区间内的元素的内容。例如替换,删除等等

    非质变算法:是指运算过程中不会更改区间内的元素内容。例如查找、计数、遍历、寻找极值等等

     

    迭代器:容器和算法之间粘合剂

    提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式。

    每个容器都有自己专属的迭代器

    迭代器使用非常类似于指针,初学阶段我们可以先理解迭代器为指针

    迭代器种类:

    种类功能支持运算
    输入迭代器对数据的只读访问只读,支持++、==、!=
    输出迭代器对数据的只写访问只写,支持++
    前向迭代器读写操作,并能向前推进迭代器读写,支持++、==、!=
    双向迭代器读写操作,并能向前和向后操作读写,支持++、--
    随机访问迭代器读写操作,可以以跳跃的方式访问任意数据,功能最强的迭代器读写,支持++、--、[n]、-n、<、<=、>、>=

    常用的容器中迭代器种类为双向迭代器,和随机访问迭代器。

    2.5 容器算法迭代器初识

    了解STL中容器、算法、迭代器概念之后,我们利用代码感受STL的魅力

    STL中最常用的容器为Vector,可以理解为数组,下面我们将学习如何向这个容器中插入数据、并遍历这个容器。

    2.5.1 vector存放内置数据类型

    容器: vector

    算法: for_each

    迭代器: vector<int>::iterator

    示例如下:

    2.5.2 Vector存放自定义数据类型

    vector中存放自定义数据类型Person,并打印输出。示例如下:

    2.5.3 Vector容器嵌套容器

    容器中嵌套容器,我们将所有数据进行遍历输出。示例如下:

    3 STL- 常用容器

    3.1 string容器

    3.1.1 string基本概念

    本质:string是C++风格的字符串,而string本质上是一个类

    string和char * 区别:

    特点:

    string 类内部封装了很多成员方法

    例如:查找find、拷贝copy、删除delete、 替换replace、插入insert

    string管理char*所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责

    3.1.2 string构造函数

    构造函数原型:

    示例如下:

    总结:string的多种构造方式没有可比性,灵活使用即可。

    3.1.3 string赋值操作

    功能描述:给string字符串进行赋值。

    赋值的函数原型:

    示例如下:

    总结:string的赋值方式很多,operator= 这种方式是比较常用的。

    3.1.4 string字符串拼接

    功能描述:实现在字符串末尾拼接字符串

    函数原型:

    示例如下:

    总结:字符串拼接的重载版本很多,记住几种即可。

    3.1.5 string查找和替换

    功能描述:

    函数原型:

    示例如下:

    总结:

    3.1.6 string字符串比较

    功能描述:字符串之间的比较

    比较方式:字符串比较是按字符的ASCII码进行对比

    函数原型:

    示例:

    总结:字符串对比主要是用于比较两个字符串是否相等,判断谁大谁小的意义并不是很大。

    3.1.7 string字符存取

    string中单个字符存取方式有两种:

    示例如下:

    总结:string字符串中单个字符存取有两种方式,利用 [ ] 或 at。

    3.1.8 string插入和删除

    功能描述:对string字符串进行插入和删除字符操作

    函数原型:

    示例如下:

    总结:插入和删除的起始下标都是从0开始。

    3.1.9 string子串

    功能描述:从字符串中获取想要的子串

    函数原型:

    示例如下:

    总结:灵活的运用求子串功能,可以在实际开发中获取有效的信息。

    3.2 vector容器

    3.2.1 vector基本概念

    功能:vector数据结构和数组非常相似,也称为单端数组

    vector与普通数组区别:不同之处在于数组是静态空间,而vector可以动态扩展

    动态扩展:并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间

     

     

    注意:vector容器的迭代器是支持随机访问的迭代器。最常用的就是v.begin()v.end()

    3.2.2 vector构造函数

    功能描述:创建vector容器

    函数原型:

    示例如下:

    总结:vector的多种构造方式没有可比性,灵活使用即可。

    3.2.3 vector赋值操作

    功能描述:给vector容器进行赋值

    函数原型:

    示例如下:

    总结: vector赋值方式比较简单,使用operator=,或者assign都可以。

    3.2.4 vector容量和大小

    功能描述:对vector容器的容量和大小操作

    函数原型:

    示例如下:

    3.2.5 vector插入和删除

    功能描述:对vector容器进行插入、删除操作

    函数原型:

    示例如下:

    3.2.6 vector数据存取

    功能描述:对vector中的数据的存取操作

    函数原型:

    示例如下:

    总结:

    3.2.7 vector互换容器

    功能描述:实现两个容器内元素进行互换

    函数原型:swap(vec); 将vec与本身的元素互换

    示例如下:

    总结:swap可以使两个容器互换,可以达到实用的收缩内存效果。

    3.2.8 vector预留空间

    功能描述:减少vector在动态扩展容量时的扩展次数

    函数原型:reserve(int len); 容器预留len个元素长度,预留位置不初始化,元素不可访问。

    示例如下:

    总结:如果数据量较大,可以一开始利用reserve预留空间,减少vector在动态扩展容量时的扩展次数。

    3.3 deque容器

    3.3.1 deque容器基本概念

    功能:双端数组,可以对头端进行插入删除操作

    deque与vector区别:

     

    deque内部工作原理:

    deque内部有个中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据

    中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间

     

    注意:deque容器的迭代器也是支持随机访问的。

    3.3.2 deque构造函数

    功能描述:deque容器构造

    函数原型:

    示例如下:

    总结:deque容器和vector容器的构造方式几乎一致,灵活使用即可。

    3.3.3 deque赋值操作

    功能描述:给deque容器进行赋值

    函数原型:

    示例如下:

    总结:deque赋值操作也与vector相同,需熟练掌握。

    3.3.4 deque大小操作

    功能描述:对deque容器的大小进行操作

    函数原型:

    示例如下:

    注意:deque没有容量的概念。

    3.3.5 deque 插入和删除

    功能描述:向deque容器中插入和删除数据

    函数原型:

    两端插入操作:

    指定位置操作:

    示例如下:

    注意:插入和删除提供的位置是迭代器!

    3.3.6 deque 数据存取

    功能描述:对deque 中的数据的存取操作

    函数原型:

    示例如下:

    总结:

    3.3.7 deque 排序

    功能描述:利用算法实现对deque容器进行排序

    算法:sort(iterator beg, iterator end) 对beg和end区间内元素进行排序

    示例如下:

    总结:sort算法非常实用,使用时包含头文件 algorithm即可。对于支持随机访问的迭代器的容器,都可以直接利用sort()算法进行排序,比如:vector容器也可以利用sort()进行排序。

    3.4 案例-评委打分

    3.4.1 案例描述

    有5名选手:选手ABCDE,10个评委分别对每一名选手打分,去除最高分,去除最低分,取平均分。

    3.4.2 实现步骤

    1. 创建五名选手,放到vector中
    2. 遍历vector容器,取出来每一个选手,执行for循环,可以把10个评分打分存到deque容器中
    3. sort算法对deque容器中分数排序,去除最高和最低分
    4. deque容器遍历一遍,累加总分
    5. 获取平均分

    示例代码:

    总结: 选取不同的容器操作数据,可以提升代码的效率。

    3.5 stack容器

    3.5.1 stack 基本概念

    概念:stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口。

     

     

    栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为。

    栈中进入数据称为:入栈 push

    栈中弹出数据称为:出栈 pop

    3.5.2 stack 常用接口

    功能描述:栈容器常用的对外接口

    构造函数:

    赋值操作:

    数据存取:

    大小操作:

    示例如下:

    3.6 queue 容器

    3.6.1 queue 基本概念

    概念:Queue是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口。

    队列容器允许从一端新增元素,从另一端移除元素

    队列中只有队头和队尾才可以被外界使用,因此队列不允许有遍历行为

    队列中进数据称为:入队 push

    队列中出数据称为:出队 pop

    3.6.2 queue 常用接口

    功能描述:栈容器常用的对外接口

    构造函数:

    赋值操作:

    数据存取:

    大小操作:

    示例如下:

    3.7 list容器

    3.7.1 list基本概念

    功能:将数据进行链式存储

    链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的

    链表的组成:链表由一系列结点组成

    结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域

    STL中的链表是一个双向循环链表:双向是指针域有两个指针,一个指向前一个节点,一个指向后一个节点。循环是第一个节点的头指针指向最后一个节点,最后一个节点的尾指针指向第一个节点。

     

     

    由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器

    list的优点:

    list的缺点:

    总结:STL中List和vector是两个最常被使用的容器,各有优缺点,要根据需求合理选择。

    3.7.2 list构造函数

    功能描述:创建list容器

    函数原型:

    示例如下:

    总结:list的构造方式类似于其他几个STL常用容器。

    3.7.3 list 赋值和交换

    功能描述:给list容器进行赋值,以及交换list容器

    函数原型:

    示例如下:

    3.7.4 list 大小操作

    功能描述:对list容器的大小进行操作

    函数原型:

    示例如下:

    3.7.5 list 插入和删除

    功能描述:对list容器进行数据的插入和删除

    函数原型:

    示例如下:

    3.7.6 list 数据存取

    功能描述:对list容器中数据进行存取

    函数原型:

    示例如下:

    注意:list容器中不可以通过[ ]或者at方式访问数据。

    3.7.7 list 反转和排序

    功能描述:将容器中的元素反转,以及将容器中的数据进行排序

    函数原型:

    示例如下:

    注意:对于不支持随机访问迭代器的容器,要使用成员函数来进行排序。

    3.7.8 排序案例

    案例描述:将Person自定义数据类型进行排序,Person中属性有姓名、年龄、身高

    排序规则:按照年龄进行升序,如果年龄相同按照身高进行降序

    示例如下:

    总结:

    3.8 set/multiset 容器

    3.8.1 set基本概念

    特点:所有元素都会在插入时自动被排序

    本质:set/multiset属于关联式容器,底层结构是用二叉树实现。

    set和multiset区别

    3.8.2 set构造和赋值

    功能描述:创建set容器以及赋值

    构造:

    赋值:

    示例如下:

    总结:

    3.8.3 set大小和交换

    功能描述:统计set容器大小以及交换set容器

    函数原型:

    示例如下:

    3.8.4 set插入和删除

    功能描述:set容器进行插入数据和删除数据

    函数原型:

    示例如下:

    3.8.5 set查找和统计

    功能描述:对set容器进行查找数据以及统计数据

    函数原型:

    示例如下:

    总结:

    3.8.6 set和multiset区别

    区别:

    示例如下:

    总结:

    3.8.7 pair对组创建

    功能描述:成对出现的数据,利用对组可以返回两个数据

    两种创建方式:

    示例如下:

    3.8.8 set容器排序

    set容器默认排序规则为从小到大,如何改变排序规则?

    利用仿函数,可以改变排序规则。

    示例一 set存放内置数据类型

    总结:利用仿函数可以指定set容器的排序规则。

    示例二 set存放自定义数据类型

    总结:对于自定义数据类型,set必须指定排序规则才可以插入数据。

    3.9 map/multimap容器

    3.9.1 map基本概念

    简介:

    本质:map/multimap属于关联式容器,底层结构是用二叉树实现。

    优点:可以根据key值快速找到value值

    map和multimap区别

    3.9.2 map构造和赋值

    功能描述:对map容器进行构造和赋值操作

    函数原型:

    构造:

    赋值:

    示例如下:

    总结:map中所有元素都是成对出现,插入数据时候要使用对组。

    3.9.3 map大小和交换

    功能描述:统计map容器大小以及交换map容器

    函数原型:

    示例如下:

    3.9.4 map插入和删除

    功能描述:map容器进行插入数据和删除数据

    函数原型:

    示例如下:

    3.9.5 map查找和统计

    功能描述:对map容器进行查找数据以及统计数据

    函数原型:

    示例如下:

    3.9.6 map容器排序

    map容器默认排序规则为 按照key值进行 从小到大排序,如何改变排序规则?

    利用仿函数,可以改变排序规则

    示例如下:

    总结:

    3.10 案例-员工分组

    3.10.1 案例描述

    3.10.2 实现步骤

    1. 创建10名员工,放到vector中
    2. 遍历vector容器,取出每个员工,进行随机分组
    3. 分组后,将员工部门编号作为key,具体员工作为value,放入到multimap容器中
    4. 分部门显示员工信息

    案例代码:

    总结:当数据以键值对形式存在,可以考虑用map 或 multimap。

    4 STL- 函数对象

    4.1 函数对象

    4.1.1 函数对象概念

    概念:

    本质:

    函数对象(仿函数)是一个,不是一个函数

    4.1.2 函数对象使用

    特点:

    示例如下:

    4.2 谓词

    4.2.1 谓词概念

    概念:

    4.2.2 一元谓词

    示例如下:

    4.2.3 二元谓词

    示例如下:

    总结:前面已经有好多改变算法策略的做法,这里做一个小结。List排序,使用成员函数L.sort(),里面传入一个bool返回值的全局函数名来指定算法策略。set和map在容器初始化的时候就指定算法策略,例如:set<int,MyCompare> s2;map<int, int, MyCompare> m;其中MyCompare是仿函数类名。而标准算法库下的sort()以及find_if()都是传入仿函数的匿名对象。

    4.3 内建函数对象

    4.3.1 内建函数对象意义

    概念:STL内建了一些函数对象

    分类:

    用法:

    4.3.2 算术仿函数

    功能描述:

    仿函数原型:

    示例如下:

    注意:使用内建函数对象时,需要引入头文件 #include <functional>

    4.3.3 关系仿函数

    功能描述:实现关系对比

    仿函数原型:

    示例如下:

    总结:关系仿函数中最常用的就是greater<>大于,常用于改变算法策略。

    4.3.4 逻辑仿函数

    功能描述:实现逻辑运算

    函数原型:

    示例如下:

    5 STL- 常用算法

    概述

    5.1 常用遍历算法

    算法简介:

    5.1.1 for_each

    功能描述:实现遍历容器

    函数原型:

    for_each(iterator beg, iterator end, _func);

    遍历算法 遍历容器元素

    beg 开始迭代器

    end 结束迭代器

    _func 函数或者函数对象,普通函数用函数名、仿函数用匿名对象

    示例如下:

    总结:for_each是最常用遍历算法,需要熟练掌握。

    5.1.2 transform

    功能描述:搬运容器到另一个容器中

    函数原型:

    transform(iterator beg1, iterator end1, iterator beg2, _func);

    beg1 源容器开始迭代器

    end1 源容器结束迭代器

    beg2 目标容器开始迭代器

    _func 函数或者函数对象

    示例如下:

    总结: 搬运的目标容器必须要提前开辟空间,否则无法正常搬运!搬运不止能进行原模原样的搬运,还能对其进行一些运算操作,再搬到目标容器。

    5.2 常用查找算法

    算法简介:

    5.2.1 find

    功能描述:查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器end()

    函数原型:

    find(iterator beg, iterator end, value);

    按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置

    beg 开始迭代器

    end 结束迭代器

    value 查找的元素

    示例如下:

    总结: 利用find可以在容器中找指定的元素,返回值是迭代器

    5.2.2 find_if

    功能描述:按条件查找元素

    函数原型:

    find_if(iterator beg, iterator end, _Pred);

    按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置

    beg 开始迭代器

    end 结束迭代器

    _Pred 函数或者谓词(返回bool类型的仿函数)

    示例如下:

    总结:find_if按条件查找使查找更加灵活,提供的仿函数可以改变不同的策略。

    5.2.3 adjacent_find

    功能描述:查找相邻重复元素

    函数原型:

    adjacent_find(iterator beg, iterator end);

    查找相邻重复元素,返回相邻元素的第一个位置的迭代器

    beg 开始迭代器

    end 结束迭代器

    示例如下:

    总结:这个算法不常用,但是如果用到要记得,省的自己写函数。

    5.2.4 binary_search(二分查找)

    功能描述:查找指定元素是否存在

    函数原型:

    bool binary_search(iterator beg, iterator end, value);

    查找指定的元素,查到 返回true 否则false

    注意: 在无序序列中不可用

    beg 开始迭代器

    end 结束迭代器

    value 查找的元素

    示例如下:

    总结:二分查找法查找效率很高,值得注意的是查找的容器中元素必须的有序序列,如果无序,结果可能有误!

    5.2.5 count

    功能描述:统计元素个数

    函数原型:

    count(iterator beg, iterator end, value);

    统计元素出现次数

    beg 开始迭代器

    end 结束迭代器

    value 统计的元素

    示例如下:

    总结: 统计自定义数据类型时候,需要配合重载 operator==

    5.2.6 count_if

    功能描述:按条件统计元素个数

    函数原型:

    count_if(iterator beg, iterator end, _Pred);

    按条件统计元素出现次数

    beg 开始迭代器

    end 结束迭代器

    _Pred 谓词(返回bool类型的仿函数),以匿名对象的方式传入

    示例如下:

    总结:按值统计用count,按条件统计用count_if。

    5.3 常用排序算法

    算法简介:

    5.3.1 sort

    功能描述:对容器内元素进行排序

    函数原型:

    sort(iterator beg, iterator end, _Pred);

    按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置

    beg 开始迭代器

    end 结束迭代器

    _Pred 谓词,用来指定特殊的排序规则

    示例如下:

    总结:sort属于开发中最常用的算法之一,需熟练掌握。

    5.3.2 random_shuffle

    功能描述:洗牌 指定范围内的元素随机调整次序

    函数原型:

    random_shuffle(iterator beg, iterator end);

    指定范围内的元素随机调整次序

    beg 开始迭代器

    end 结束迭代器

    示例如下:

    总结:random_shuffle洗牌算法比较实用,使用时记得加随机数种子。

    5.3.3 merge

    功能描述:两个容器元素合并,并存储到另一容器中

    函数原型:

    merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

    容器元素合并,并存储到另一容器中

    注意:两个容器必须是有序的,合并出的目标容器也是有序的,有点分组排序降低复杂度的味道

    beg1 容器1开始迭代器

    end1 容器1结束迭代器

    beg2 容器2开始迭代器

    end2 容器2结束迭代器

    dest 目标容器开始迭代器

    示例如下:

    总结:merge合并的两个容器必须的有序序列。

    5.3.4 reverse

    功能描述:将容器内元素进行反转

    函数原型:

    reverse(iterator beg, iterator end);

    反转指定范围的元素

    beg 开始迭代器

    end 结束迭代器

    示例如下:

    5.4 常用拷贝和替换算法

    算法简介:

    5.4.1 copy

    功能描述:容器内指定范围的元素拷贝到另一容器中

    函数原型:

    copy(iterator beg, iterator end, iterator dest);

    beg 开始迭代器

    end 结束迭代器

    dest 目标起始迭代器

    示例如下:

    总结:利用copy算法在拷贝时,目标容器记得提前开辟空间。copy算法用的比较少,直接=赋值简单。

    5.4.2 replace

    功能描述:将容器内指定范围的旧元素修改为新元素

    函数原型:

    replace(iterator beg, iterator end, oldvalue, newvalue);

    将区间内旧元素 替换成 新元素

    beg 开始迭代器

    end 结束迭代器

    oldvalue 旧元素

    newvalue 新元素

    示例如下:

    5.4.3 replace_if

    功能描述: 将区间内满足条件的元素,替换成指定元素

    函数原型:

    replace_if(iterator beg, iterator end, _pred, newvalue);

    按条件替换元素,满足条件的替换成指定元素

    beg 开始迭代器

    end 结束迭代器

    _pred 谓词

    newvalue 替换的新元素

    示例如下:

    总结:replace_if按条件查找,可以利用仿函数灵活筛选满足的条件。

    5.4.4 swap

    功能描述:互换两个容器的元素

    函数原型:

    swap(container c1, container c2);

    互换两个容器的元素,两个容器必须是同种类型

    c1容器1

    c2容器2

    示例如下:

    总结:swap交换容器时,注意交换的容器要同种类型。

    5.5 常用算术生成算法

    注意:算术生成算法属于小型算法,使用时包含的头文件为 #include <numeric>

    算法简介:

    5.5.1 accumulate

    功能描述:计算区间内 容器元素累计总和

    函数原型:

    accumulate(iterator beg, iterator end, value);

    计算容器元素累计总和

    beg 开始迭代器

    end 结束迭代器

    value 起始值

    示例如下:

    总结:accumulate使用时头文件注意是 numeric,这个算法很实用。

    5.5.2 fill

    功能描述:向容器中填充指定的元素

    函数原型:

    fill(iterator beg, iterator end, value);

    向容器中填充元素

    beg 开始迭代器

    end 结束迭代器

    value 填充的值

    示例如下:

    5.6 常用集合算法

    算法简介:

    5.6.1 set_intersection

    功能描述:求两个容器的交集

    函数原型:

    set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

    求两个集合的交集

    注意:两个集合必须是有序序列

    beg1 容器1开始迭代器

    end1 容器1结束迭代器

    beg2 容器2开始迭代器

    end2 容器2结束迭代器

    dest 目标容器开始迭代器

    示例如下:

    总结:

    5.6.2 set_union

    功能描述:求两个集合的并集

    函数原型:

    set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

    求两个集合的并集

    注意:两个集合必须是有序序列

    beg1 容器1开始迭代器

    end1 容器1结束迭代器

    beg2 容器2开始迭代器

    end2 容器2结束迭代器

    dest 目标容器开始迭代器

    示例如下:

    总结:

    5.6.3 set_difference

    功能描述:求两个集合的差集

    函数原型:

    set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

    求两个集合的差集

    注意:两个集合必须是有序序列

    beg1 容器1开始迭代器

    end1 容器1结束迭代器

    beg2 容器2开始迭代器

    end2 容器2结束迭代器

    dest 目标容器开始迭代器

    示例如下:

    总结: