c++编程

目录

 

C++ 提高编程

主要针对C++泛型编程和STL技术

一、 模板

1、 概念

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

模板特点

  • 模板不可以直接使用,它只是一个框架
  • ​ 模板的通用并不是万能的

2、 函数模板

  • C++ 另一种编程思想为泛型编程,主要利用的技术就是模板
  • C++ 提供两种模板机制:函数模板 和 类模板

2.1 函数模板语法

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

语法

   
   

参数

  • template:声明创建模板
  • typename:表明其后面的符号是一种数据类型,可以用class来代替
  • T:通用的数据类型,名称可以替换,通常为大写字母
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

模板可以将数据类型参数化

模板的使用方法

  • 自动推导
  • 显示指定类型

2.2 注意事项

注意事项

  • 自动推导数据类型,必须推导出一致的数据类型 T,才可以使用
  • 模板必须要确定出 T 的数据类型,才可以使用

2.3 普通函数和函数模板的区别

  • 普通函数调用时可以发生自动类型转换(隐式类型装换)
  • 函数模板调用时,如果利用自动类型推导,不会发生隐式类型装换
  • 如果利用显示指定类型的方法,可以发生隐式类型转换

2.4 普通函数和函数模板的调用规则

调用规则如下

  1. 如果函数模板和普通函数都可以实现,优先调用普通函数

  2. 可以通过空模板参数列表强制调用函数模板

       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
  3. 函数模板也可以发生重载

  4. 如果函数模板可以产生更好的匹配模式,优先调用函数模板

       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       

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

2.5 模板的局限性

  • 模板的通用性并不是万能的

如果传入的是一个元组以及自定义数据类型,就无法实现了

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

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

学习模板并不是为了写模板,而是在STL中能够运用系统提供的模板

3、 类模板

3.1 类模板语法

类模板作用

  • 建立一个通用类,类中成员数据类型可以不具体制定,用一个虚拟的类型代表

语法

   
   

参数

  • template:声明创建模板
  • typename:表明其后面的符号是一种数据类型,可以用class来代替
  • T:通用的数据类型,名称可以替换,通常为大写字母
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

3.2 类模板和函数模板的区别

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

  1. 类模板没有自动类型推导的使用方式

  2. 类模板在模板参数列表中可以有默认参数

       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       

3.3 使用时机

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

  • 普通类中的成员函数一开始就可以创建
  • 类模板中的成员函数在调用时才创建
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

3.4 类模板对象函数做参数

类模板实例出的对象,向函数传参

一共有三种传入方式

  • 指定传入的数据类型:直接显示对象的数据类型

    •    
         
  • 参数模板化:将对象中的参数变为模板进行传递

    •    
         
         
  • 整个类模板化:将这个对象类型模板化进行传递

    •    
         
         
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

查看数据类型的方式

   

3.5 类模板与继承

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

  • 当子类继承的父类是一个类模板时,子类在声明的时候,要指定出父类中 T 的数据类型
  • 如果不指定,编译器无法给子类分配内存
  • 如果想灵活指定出父类的 T 的类型,子类也需变为模板
   
   
   
   
   
   
   
   
   
   
   
   

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

能够掌握类模板中的成员函数类外实现

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

3.7 类模板文件编写

掌握类模板成员函数分文件编写产生的问题以及解决方式

问题

  • 类模板中成员函数创建时机是在调用阶段,导致文件编写是链接不到

解决

  1. 直接包含 .cpp 源文件
  2. 将声明和实现写到同一个文件中,并更改后缀名为 .hpp,hpp 是约定的名称,并不是强制

person.hpp 中代码

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

程序入口代码

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

主要解决方式是第二种,将类模板成员函数写到一起,并将后缀名改为 .hpp

3.8 类模板和友元

掌握类模板配合友元函数的类内和类外实现

  • 全局函数类内实现:直接在类内声明友元即可
  • 全局函数类外实现:需要提前让编译器知道全局函数的存在
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

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

3.9 数组类封装

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

  • 可以对内置数据类型以及自定义数据类型的数据进行存储
  • 将数组中的数据存储到堆区
  • 构造函数中可以传入数组的容量
  • 提供对应的拷贝构造函数以及opertator=防止出现浅拷贝的问题
  • 可以通过下标方式访问数组中的元素
  • 可以获取数组中当前元素个数和数组数量

myArray.hpp 中代码

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

主函数调用

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

该数组也可以存储自定义数据类型

二、 STL 初识

1、 基本概念

  • STL 基本模板库
  • STL 从广义上分为容器、算法和迭代器
  • 容器和算法事件通过迭代器无缝连接
  • STL 几乎所有的代码都采用了模板类或模板函数

2、 STL 六大组件

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

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

2.1 容器、算法、迭代器

容器:置物之所也

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

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

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

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

算法:问题之解也

有限的步骤,解决逻辑或数学上的问题,这叫做算法

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

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

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

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

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

迭代器使用非常类似于指针

迭代器种类

   
     
     
     
     
     

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

3、 迭代器初始

3.1 vector 存放内置数据类型

容器:vector

算法:for_each

迭代器:vector<int>::iterator

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

3.2 vector 存放自定义数据类型

vector 中存放自定义数据类型,并打印输出

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

3.3 vector 中嵌套容器

容器中嵌套容器,我们将所有数据遍历输出

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

三、 STL 常用容器

每个容器都要添加头文件

1、 string 容器

1.1 string 基本概念

本质

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

string 和 char* 的区别

  • char* 是一个指针
  • string 是一个类,类内部封装了 char* ,管理这个字符串,是一个 char* 容器

特点

  1. string 类内部封装了很多成员方法
    • 例如:find, copy, delete, replace, insert
  2. string 管理 char* 所分配的内存,不用担心复制和取值越界等,由类内进行负责

1.2 string 构造函数

构造函数原型

  • string(); 创建一个空字符串

    string(const char* s); 使用字符串 s 初始化

  • string(const string& str); 使用一个 string 对象初始化另一个 string 对象

  • string(int, char c); 使用 n 个字符 c 初始化

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

string 的多种构造方式没有可比性,灵活性较高

1.3 string 赋值操作

功能描述

  • 给 string 字符串进行赋值

赋值函数原型

   
   
   
   
   
   
   

1.4 string 字符串拼接

功能描述

  • 实现在字符串末尾拼接字符串

函数原型

   
   
   
   
   
   
   

1.5 string 查找和替换

功能描述

  • 查找:查找指定字符是否存在
  • 替换:在指定的位置替换字符串

函数原型

   
   
   
   
   
   
   
   
   
   

总结

  • find查找是从左往右,rfind是从右往左
  • find找到字符串后返回查找的第一个字符位置,找不到返回-1
  • replace在替换时,要指定从哪个位置起,多少个字符,替换成什么样的字符串

1.6 string 字符串比较

功能描述

  • 字符串之间的比较

比较方式

  • 字符串比较时按字符的ASCII码进行对比
  • = 返回 0
  • < 返回 1
  • > 返回 -1

函数原型

   
   

主要比较两个字符串是否相等

1.7 string 字符存取

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

   
   
   

可以修改字符,str[int n] = 'c'

1.8 string 插入和删除

功能描述

  • 对 string 字符串进行插入合删除字符操作

函数原型

   
   
   
   

1.9 string 中的子串

功能描述

  • 从字符串中获取想要的子串

函数原理

   

2、 vector 容器

2.1 vector 基本概念

功能

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

vector 与普通数组的区别

  • 不同之处在于数组是静态空间,而 vector 可以动态扩展

    动态扩展

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

    • vector 容器的迭代是支持随机访问的迭代器

2.2 vector 构造函数

功能描述

  • 创建 vector 容器

函数原型

   
   
   
   

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

2.3 vector 赋值操作

功能描述

  • 给 vector 容器进行赋值

函数原理

   
   
   

2.4 vector 大小操作

功能描述

  • 对 vector 容器的容量和大小操作

函数原型

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

容量大于等于大小

2.5 vector 插入和删除

功能描述

  • 对 vector 容器进行插入、删除操作

函数原型

   
   
   
   
   
   
   

v1.insert(v1.begin(), 100); // 第一个参数是迭代器

2.6 vector 数据存取

功能描述

  • 对 vector 中的数据的存取操作

数据原型

   
   
   
   

2.7 vector 互换容器

功能描述

  • 实现两个容器内元素进行互换

函数原型

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

作用:巧用 swap 可以收缩内存空间vector<int> (v).swap(v); // 使用匿名对象

2.8 vector 预留空间

功能描述

  • 减少 vector 在动态扩展容量时的扩展次数

函数原理

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

如果数据量比较大,可以一开始利用 reserve 预留空间

3、 deque 容器

3.1 deque 基本概念

功能

  • 双端数组:可以对头部进行插入删除操作

deque 和 vector 区别

  • vector 对于头部的插入和删除的效率较低,数据量大,效率低
  • deque 相对而言,对头部的插入删除速度会比 vector 快
  • vector 访问元素时的速度会比 deque 快,这和两者实现有关

deque 内部工作原理

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

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

deque 容器的迭代器也是支持随机访问的

3.2 deque 构造函数

功能描述

  • deque 容器构造

函数原理

   
   
   
   

3.3 deque 赋值操作

功能描述

  • 给 deque 容器进行赋值

函数原理

   
   
   

3.4 deque 大小操作

功能描述

  • 对 deque 容器的大小进行操作

函数原理

   
   
   
   

deque 没有容量的概念

3.5 deque 插入和删除

功能描述

  • 向 deque 容器中插入和删除数据

函数原型

   
   
   
   
   
   
   
   
   
   
   
   
   

里面的 pos 是迭代器指针的位置

3.6 deque 数据存取

功能描述

  • 对 deque 中的数据的存取操作

函数原型

   
   
   
   

3.7 deque 排序

功能描述

  • 利用算法对 deque 中的数据进行排序

函数原型

   

注意使用时,要包含头文件#include <algorithm>

对于支持随机访问的迭代器的容器,都可以利用 sort 算法直接对其进行排序

vector 也可以利用 sort 进行排序

4、 案例-评委打分

4.1 案例描述

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

4.2 实现步骤

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

5、 stack 容器

5.1 stack 基本概念

概念:stack 是一种先进后出的数据结构,它只有一个出口

栈中进入元素称为入栈:push();

栈中弹出元素称为出栈:pop();

5.2 stack 常用接口

功能描述:

  • 栈容器常用的对外接口
5.2.1 构造函数
   
   
5.2.2 赋值操作
   
5.2.3 大小操作
   
   
5.2.4 数据存取
   
   
   

6、 queue 容器

6.1 queue 基本概念

概念:

  • queue 是一种先进先出的数据结构,它有两个出口

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

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

队列中进数据称为入队:push();

队列中出数据称为出队:pop();

6.2 queue 常用接口

功能描述

  • 栈容器常用的对外接口
6.2.1 构造函数
   
   
6.2.2 赋值操作
   
6.2.3 大小操作
   
   
6.2.4 数据存取
   
   
   
   

7、 list 容器

7.1 list 基本概念

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

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

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

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

STL 中的链表是一个双向循环链表

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

list 优点

  • 采用动态分配内存,不会造成内存浪费和溢出
  • 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量数据

list 缺点

  • 链表灵活,但是空间(指针域)和时间(遍历)额外耗费较大

list 有一个重要的性质,插入操作和删除操作都不会造成原有 list 迭代器的失效,这在 vector 是不成立的

总结:STL 中 list 和 vector 是最常被使用的容器,各有优缺点

7.2 list 构造函数

功能描述

  • 创建 list 容器

函数原型

   
   
   
   

7.3 list 赋值和交换

功能描述

  • 给 list 容器进行赋值,以及交换 list 容器

函数原型

   
   
   
   

7.4 list 大小操作

功能描述

  • 对 list 容器的大小进行操作

函数原型

   
   
   
   

7.5 list 插入和删除

功能描述

  • 对 list 容器进行数据的插入和删除

函数原型

   
   
   
   
   
   
   
   
   
   
   

7.6 list 数据存取

功能描述

  • 对 list 容器中数据进行存取

函数原型

   
   

注意不能使用 at 和 [] 的方式访问容器中的元素

原因是 list 本质是链表,而不是使用连续线性空间存储数据,迭代器也是不支持随机访问的

迭代器不支持随机访问,支持双向访问

7.7 list 反转和排序

功能描述

  • 将容器中的元素反转,以及将容器中的数据进行排序

函数原型

   
   

所有不支持随机访问迭代器容器,不可以使用标准算法

不支持随机访问迭代器的容器,内部会提供对应一些算法

对于自定义数据类型,sort() 括号可以添加一个排序规则

高级排序只是在排序规则上再进行一次逻辑规则的制定,并不复杂

   
   
   
   
   
   
   
   
   
   
   
   
   
   

8、 set / multiset 容器

8.1 set 基本概念

简介:

  • 所有元素都会在插入时自动被排序

本质

  • set 属于关联式容器,底层结构使用二叉树实现

set 和 multiset 区别

  • set 不允许容器中有重复元素
  • multiset 允许容器中有重复元素

8.2 set 构造和赋值

功能描述

  • 创建 set 容器以及赋值

函数原型

   
   
   
   
   

8.3 set 大小和交换

功能描述

  • 统计 set 容器大小及交换 set 容器

函数原型

   
   
   

8.4 set 插入合删除

功能描述

  • set 容器进行插入和删除操作

函数原型

   
   
   
   
   

8.5 set 查找和统计

功能描述

  • 对 set 容器进行查找数据以及进行数据统计

函数原型

   
   

8.6 set 和 multiset 区别

掌握 set 和 multiset 的区别

区别

  • set 不可以插入重复数据,而 multiset 可以

  • set插入数据的同时会返回插入结果,表示插入是否成功

    ret.second用来查看是否插入成功

  • multiset 不会检测数据,因此可以重复插入数据

8.7 pair 对组创建

功能描述

  • 成功出现的数据,利用对组可以返回两个数据

两种创建方式

   
   

两种创建方式,记住一种就可以了

使用方式

   
   

8.8 set 排序

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

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

对于自定义的数据类型,要创建排序规则,必须要指定排序规则

   
   
   
   
   
   
   
   
   

9、 map / multimap 容器

9.1 map 基本概念

简介:

  • map 中所有元素都是 pair
  • pair 中第一个元素为 key(键值),起到索引作用,第二个元素为 value(实值)
  • 所有元素都会根据元素的键值自动排序

本质:

  • map/ multimap 属于关联式容器,底层结构通过二叉树实现

优点:

  • 可以根据 key 值快速找到 value 值

map/ multimap 区别

  • map 不允许容器中有重复 key 值元素
  • multimap 允许容器中有重复 key 值元素

9.2 map 构造和赋值

功能描述:

  • 对 map 容器进行构造和赋值操作

函数原型

   
   
   
   

map 容器中所有元素都是成对出现的,插入数据的时候要使用对组

9.3 map 大小和交换

功能描述:

  • 对 map 容器大小以及交换 map 值

函数原型

   
   
   

9.4 map 插入和删除

功能描述:

  • map 容器进行插入和删除数据

函数原型

   
   
   
   
   

注意插入的是对组

   
   
   
   
   
   
   
   

9.5 map 查找和统计

功能描述:

  • 对 map 容器进行查找数据和统计数据

函数原型

   
   

9.6 map 排序

map 容器默认排序规则为按照键升序排序

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

其和 [set 排序](#8.8 set 排序)类似

10、 案例-员工分组

10.1 案例描述

  • 公司每天招聘10个员工,10名员工进入公司后,需要指派员工在哪个部门工作
  • 员工信息:姓名、工资组成;部门分为:策划、美术、研发
  • 随机给10名员工分配部门和工资
  • 通过 multimap 进行信息的插入 key:部门编号、value:员工
  • 分部门显示员工

10.2 实现步骤

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

10.3 代码演示

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

四、 STL 函数对象

1、 函数对象

1.1 基本概念

概念:

  • 重载函数调用操作符的类,其对象常称为函数对象
  • 函数对象使用重载的 () 时,行为类似函数调用,也叫仿函数

本质:

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

1.2 使用方法

特点:

  • 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
  • 函数对象超出普通函数的概念,函数对象可以有自己的状态
  • 函数对象可以作为参数传递
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

2、 谓词

2.1 谓词概念

概念

  • 返回 bool 类型的仿函数称为谓词
  • 如果 operator() 接受一个参数,那么叫做一元谓词
  • 如果 operator() 接受两个参数,那么叫做二元谓词

2.2 一元谓词

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

2.3 二元谓词

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

3、 内建函数对象

3.1 意义

概念:

  • STL 内建了一些函数对象

分类:

  • 算术仿函数
  • 关系仿函数
  • 逻辑仿函数

用法:

  • 这些仿函数所产生的对象,用法和一般函数完全相同
  • 使用内建函数对象,需要引入头文件#include <functional>

3.2 算术仿函数

功能描述:

  • 实现四则运算
  • 其中:negate 是一元运算,其他都是二元运算

仿函数原理

   
   
   
   
   
   
   
   
   
   

3.3 关系仿函数

功能描述

  • 实现关系对比

仿函数原理

   
   
   
   
   
   

3.4 逻辑仿函数

功能描述

  • 实现逻辑运算

仿函数原理

   
   
   

五、 STL 常用算法

描述:

  • 算法主要是由头文件<algorithm><functional><numeric>组成
  • <algorithm>是所有 STL 头文件中最大的一个,范围涉及到比较、交换、查找、遍历、赋值等等
  • <numeric>体积很小,只包括几个在序列上面进行简单数学运算的模块函数
  • <functional>定义了一些模快类,用以声明函数对象

1、 常用遍历算法

学习目标:

  • 掌握常用遍历算法

算法简介:

   
   

1.1 for_each

功能描述:

  • 实现遍历容器

函数原型

   

遍历算法:遍历容器元素

参数:

  • beg:开始迭代器
  • end:结束迭代器
  • _func:函数或者函数对象,一般为输出内容的函数,回调函数

1.2 transform

功能描述:

  • 搬运容器到另一个容器中

函数原型

   

目标容器要提前开辟空间,否则会报错

参数:

  • beg1:源容器开始迭代器
  • end1:源容器结束迭代器
  • beg2:目标容器开始迭代器
  • _func:函数或函数对象

2、 常用查找算法

学习目标:

  • 掌握常用的查找算法

算法简介:

   
   
   
   
   
   

2.1 find

功能描述:

  • 查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器

函数原型

   

参数:

  • beg:开始迭代器
  • end:结束迭代器
  • value:查找的元素

如果是自定义数据类型,查找时要重载等号运算符

2.2 find_if

功能描述:

  • 按条件查找元素

函数原型

   

参数:

  • beg:起始迭代器
  • end:结束迭代器
  • _Pred:函数或者谓词(返回 bool 类型的仿函数)

2.3 adjacent_find

功能描述:

  • 查找相邻重复元素

函数原型

   

参数:

  • beg:开始迭代器
  • end:结束迭代器

功能描述:

  • 查找指定元素是否存在

函数原型

   

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

参数:

  • beg:开始迭代器
  • end:结束迭代器
  • value:查找的元素

2.5 count

功能描述:

  • 统计元素个数

函数原型

   

beg:开始迭代器

end:结束迭代器

value:统计的元素

统计自定义数据类型时,要使用仿函数

   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

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

2.6 count_if

功能描述:

  • 按条件统计元素个数

函数原型

   

参数:

  • beg:开始迭代器
  • end:结束迭代器
  • _Pred:谓词

3、 常用排序算法

学习目标

  • 掌握常用的排序算法

算法简介:

   
   
   
   

3.1 sort

功能描述

  • 对容器内元素进行排序

函数原型

   

参数:

  • beg:开始迭代器
  • end:结束迭代器
  • _Pred:谓词

3.2 random_shuffle

功能描述

  • 洗牌,指定范围内的元素随机调整次序

函数原型

   

使用时记得添加随机种子

   

参数:

  • beg:起始迭代器
  • end:结束迭代器

3.3 merge

功能描述:

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

函数原型

   

注意:

  • 两个容器必须是有序的
  • 要提前给目标容器分配空间

参数:

  • beg1:容器1开始迭代器
  • end1:容器1结束迭代器
  • beg2:容器2开始迭代器
  • end2:容器2结束迭代器
  • dest:目标容器开始迭代器

3.4 reverse

功能描述

  • 将容器内元素进行反转

函数原型

   

参数:

  • beg:开始迭代器
  • end:结束迭代器

4、 常用拷贝和替换算法

学习目标

  • 掌握常用的拷贝和替换算法

算法简介

   
   
   
   

4.1 copy

功能描述:

  • 容器内指定范围的元素拷贝到另一个容器中

函数原型

   

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

需要先预定目标容器的空间

参数:

  • beg:开始迭代器
  • end:结束迭代器
  • dest:目标容器起始迭代器

4.2 replace

功能描述

  • 将容器内指定范围内的旧元素修改为新元素

函数原型

   

它会替换区间内所有满足条件的元素

参数:

  • beg:起始迭代器
  • end:结束迭代器
  • oldvalie:旧元素
  • newvalue:新元素

4.3 replace_if

功能用法

  • 将区间内满足条件的元素,替换成特定元素

函数原理

   

它会替换区间内所有满足条件的元素

参数:

  • beg:起始迭代器
  • end:结束迭代器
  • _Pred:谓词
  • newvalue:替换的新元素

4.4 swap

功能描述:

  • 互换两个容器的元素

函数原型

   

同种数据类型的容器才能互换

参数:

  • c1:容器1
  • c2:容器2

5、 常用算术生成算法

学习目标

  • 掌握常用的算术生成算法

注意:

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

算法简介

   
   

5.1 accumulate

功能描述:

  • 计算区间内元素的总和

函数原型

   

参数:

  • beg:起始迭代器
  • end:结束迭代器
  • firstValue:起始累加值

5.2 fill

功能描述:

  • 向容器中填充指定的元素

函数原型

   

参数:

  • beg:开始迭代器
  • end:结束迭代器
  • value:填充的值

6、 常用集合算法

学习目标:

  • 掌握常用的集合算法

算法简介

   
   
   

6.1 set_insersection

功能描述:

  • 求两个容器的交集,重复的元素

函数原型

   

需要提前开辟空间,最特殊的情况:大容器包含小容器,开辟空间,取小容器的 size 即可

   

参数:

  • beg1:容器1开始迭代器
  • end1:容器1结束迭代器
  • beg2:容器2开始迭代器
  • end2:容器2结束迭代器
  • dest:目标容器开始迭代器

6.2 set_union

功能描述:

  • 求两个容器的并集

函数原型

   

目标容器要提前开辟空间,最特殊的情况是两个容器没有交集

   

参数:

  • beg1:容器1开始迭代器
  • end1:容器1结束迭代器
  • beg2:容器2开始迭代器
  • end2:容器2结束迭代器
  • dest:目标容器开始迭代器

6.3 set_difference

功能描述:

  • 求两个容器的差集

函数原型

   

目标容器要提前开辟空间,最特殊的情况是两个容器没有交集,取 size 大的作为容器的空间

   

参数:

  • beg1:容器1开始迭代器
  • end1:容器1结束迭代器
  • beg2:容器2开始迭代器
  • end2:容器2结束迭代器
  • dest:目标容器开始迭代器

本文来自博客园,作者:A-L-Kun,转载请注明原文链接:https://www.cnblogs.com/liuzhongkun/p/15910727.html

 
 
posted @ 2022-02-20 21:54  专注it  阅读(217)  评论(0编辑  收藏  举报