C++学习笔记(十六):对vector进行更多的操作——泛型算法

2023-11-20

先强调一下,这里的泛型算法实际不光光是对vector的操作,对于“顺序容器”均可以。

但是什么是顺序容器:

我们都知道,容器就是一些特定类型对象的集合。而顺序容器为程序员提供了控制元素存储和访问的能力。这种容器的一个显著的特征,就是容器中元素的顺序不依赖于元素的值,而是与加入容器时的位置有关。常见的顺序容器有vector、deque(双端队列)、list(双向链表)、forward_list(单向链表)、array(固定大小数组)、string。


了解了顺序容器,现在以vector为例,做下文的说明。

顺序容器本身只定义了很少的操作,这些操作我在前面的博客(点这里)也有写过。比如添加、删除元素,访问元素、获得迭代器等。但是现实中,我们用户肯定希望有更多的操作供自己使用,比如查找、替换、删除特定元素,重新排列元素等。为了实现上面的功能,程序员可能需要写一大段代码来将其实现。

为了解决这个问题,增加对于vector的操作种类,标准库给出了一组“泛型算法(generic algorithm)”。称其“算法”,是因为他们实现了一些经典算法的公共接口,比如排序、搜索。称其为“泛型”,是因为他们可以用于不同类型的元素和多种容器类型。

 

下面讲一下具体有哪些泛型算法。

大多数的算法都定义在头文件algorithm中,标准库还在头文件numeric中定义了一组数值泛型算法。一般情况下这些算法并不直接操作容器,而是遍历由两个迭代器指定的一个元素范围。

这些算法大致可以分为下面几类:

 

一、只读算法

顾名思义,这种算法只读取其输入范围内的元素,并不改变元素。

<1>find(vec.begin() , vec.end(), val)

在vec中搜索val,返回第一个等于val的元素的迭代器。如果范围内无匹配元素,则放回vec.end()。

<2>count(vec.begin() , vec.end(), val)

在vec中搜索val,返回val在vec中出现的次数。

<3>accumulate(vec.begin() , vec.end(), val)

在vec中的元素求和,和的初始值设为val。val的类型决定了函数使用哪个加法运算符以及返回值类型。

<4>equal(vec1.begin() , vec1.end(), vec2.begin())

比较两个vector是否相等,返回值为bool型。

 

二、写容器元素算法

<1>fill(vec.begin(), vec.end(), val)

将vec中的元素重置为val


<2>fill_n(dest , n , val)

将从dest开始的n个元素重置为val。这里的dest是一个指向某个元素的迭代器。注意:这里的vec不能是空的,如果是空,那么上面的操作将会出现未知结果。

 

<3>back_inserter(vec)

向容器中添加元素的迭代器,故称之为插入迭代器。通常来说,当我们通过迭代器来给容器赋值时,值被赋予迭代器指向的元素。而当我们通过一个插入迭代器赋值时,一个与赋值号右侧值相等的元素被添加到容器中。back_inserter接收一个指向容器的引用,返回一个与该容器绑定的插入迭代器。当我们通过此迭代器赋值时,赋值运算符会调用push_back将一个具有给定值的元素添加到容器中。比如:

vector<int> vec;  //空向量

auto it = back_inserter(vec);  //通过它赋值会将元素添加到vec中

*it = 42;   //vec中现在有一个元素,值为42

我们常常使用back_inserter来创建迭代器,作为泛型算法的目的位置使用。比如:

vector<int> vec;   //空向量

fill_n(back_inserter(vec), 10 ,0);  //添加10个元素到vec。

可以发现,前面说fill_n的vec不能为空,否则将会出现未知结果,而这里back_inserter相当于给vec push_back 了10个位置,然后填充,故这里的用法是可以的。

 

<4>copy(vec1.begin(), vec1.end(), vec2.begin())

将vec1中的内容拷贝到vec2中,故这里要求vec2的长度必须要大于等于vec1的长度。

 

<5>replace(vec.begin(), vec.end(), val1 ,val2)

将vec中的所有val1都替换为val2。


<6>replace_copy(vec1.begin(), vec1.end(),vec2.begin(), val1 ,val2)

替换后vec1中的值并未改变,而是将vec1拷贝到vec2中,并将vec2中的所有val1都替换为val2。

 

三、排序

sort(vec.begin() , vec.end());

对vec中的内容按字典顺序排序

四、删除相同数据

unique(vec.begin(), vec.end());

将vec中重复的数据删除,返回指向不重复区域之后一个位置的迭代器。值得注意的是这个删除操作只是将vec中的数据清空,但是vec的大小不变。即假设原vec中有40个元素,其中重复的有5个,那么经过unique操作后,这些重复元素重复的部分就不见了,vec中非空数据变成了35个,剩下的5个空间里面的数据为空。但是vec的size仍旧为40。要想真正的删除这些元素,还需用到容器本身的操作,erase。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++学习笔记(十六):对vector进行更多的操作——泛型算法 的相关文章

随机推荐

  • Linux 版本的 SQL Server 快速安装

    SQL Server 2017 版本已经支持 Linux 安装了 出来了很长时间 我还没有实现过在 Linux 上面的应用 包括安装和高可用配置 本文就先尝试完成 Linux 版 SQL Server 的安装 经常在 Windows 下安装
  • VLC for unity 插件如何使用

    VLC for unity 插件如何使用 先去下载一个VLC播放器 安装完成后 然后导入插件链接https download csdn net my 这个插件我的另一个上传资源里有 或者到商店去下载 这个插件链接下载完是一个txt文档 里面
  • settings.json是什么?VS Code的“用户”和“工作区”

    setting json settings json是VS Code众多配置文件中的一个 可以对VS Code进行页面风格 代码格式 字体颜色大小等的编辑设置 比如可能编辑器默认的一个tab为4个空格 用户可以在setting json里面
  • C++11-14 第10讲 template template parameter(模板模板参数)

    template
  • QML类型——ListModel

    正文 列表数据Model 可以自定义格式 详细说明 ListModel是定义ListElement的容器 内容可以动态定义 也可以在QML中明确定义 可以通过count属性获得模型中数据的数量 可以使用模型的setProperty 方法来操
  • 【Linux/C++:modebus通信示例】(带初习配置概括)

    以modbus RTU为例 模拟modbus简单通信原理的代码实现 首先需要配置串口 这里使用的为Configure Virtual Serial Port Driver虚拟串口调试工具 创建COM1 COM2虚拟端口 或另创建一对串口互作
  • JAVA自学之路

    JAVA自学之路 一 学会选择 为了就业 不少同学参加各种各样的培训 决心做软件的 大多数人选的是java 或是 net 也有一些选择了手机 嵌入式 游戏 3G 测试等 那么究竟应该选择什么方向呢 我的意见是 不要太过相信各种培训机构或是抢
  • ctfshow web7

    文章目录 题目分析 解题过程 题目分析 打开题目后 有三个文章 随便点一个之后发现网址上有个后缀 id 2 应该是get传参的注入了 在后缀上加 id 1 1 显示全部文章 可能是整形注入 还是盲注 他这个过滤了空格 用 代替 详见web6
  • MySQL 8.0数据库在Win10的位置

    MySQL 8 0的配置文件位置在下面的ini文件中 C ProgramData MySQL MySQL Server 8 0 my ini C ProgramData 一般是隐藏的 修改文件夹选项可见 或者直接输入位置就能打开文件加了 m
  • wifidog浏览器弹窗认证 — 基于OpenWRT路由器

    一 移植 wifidog功能 1 功能介绍 wifidog是一种能够实现让路由器局域网设备 包括wifi连接和网线连接设备 在上网前先进行 portal认证的工具 主要应用于手机端上网认证 手机在连接wifi后会自动打开浏览器并跳转出 lo
  • C++顺序链表

    include
  • Android AutoCompleteTextView实现自动补全

    辛苦堆砌 转载请注明出处 谢谢 最近工作用到了自动补全 这里做一个简单记录 首先上我们的布局
  • 类函数重载

    函数重载必然发生在同一个作用域 重载函数 本事为不同函数 函数名和参数列表决定函数 函数必须发生在同一个作用域中 include
  • IDEA 编写JDBC 第一个示例

    知心惟有雕梁燕 自来相伴 东风不管琵琶怨 落花吹遍 一 新建一个Module 二 在此Module下新建一个包 在包再建一个包 命名为lib 三 导入mysql驱动 四 将mysql驱动添加到项目的库里 五 代码实现 package Con
  • 协同过滤算法代码

    此算法主要用来推荐的 找出ui uj两个用户同时打过分的课程集合 function getPSet uid ujd select 课程编号 from 评分 where 用户编号 ui and 课程编号 in select 课程编号 from
  • linux使用date命令获取系统时间

    转载自Linux系统date命令的参数及获取时间戳的方法 date指令相关用法示例 date 用法 date OPTION FORMAT date u utc universal MMDDhhmm CC YY ss 直接输入date dat
  • 微信小程序开发之——用户登录-登录流程(1)

    一 概述 新建微信小程序自带用户登录简化 小程序登录流程时序 二 新建微信小程序自带用户登录简化 新建的微信小程序默认有用户登录功能 将多余功能去除后 简化如下 2 1 index wxml
  • 文心一言续写太监小说《名侦探世界的巫师》

    名侦探世界的巫师 是我的童年回忆 总是想着续写一下 但是又没有时间和文笔 文心一言出了 由于目前大模型貌似可以联网 可以尝试搞一波 目录 文章1 前六个故事还能看 后面就是在重复 故事2 辣眼睛 毁童年 非请勿看 故事3 流水账 故事4 其
  • JDK介绍

    JDK JRE和JVM之间的关系 JVM是运行环境 JRE是含运行环境和相关的类库 跟node环境是一个意思 JDK目录介绍 目录名称 说明 bin 该路径下存放了JDK的各种工具命令 javac和java就放在这个目录 conf 该路径下
  • C++学习笔记(十六):对vector进行更多的操作——泛型算法

    先强调一下 这里的泛型算法实际不光光是对vector的操作 对于 顺序容器 均可以 但是什么是顺序容器 我们都知道 容器就是一些特定类型对象的集合 而顺序容器为程序员提供了控制元素存储和访问的能力 这种容器的一个显著的特征 就是容器中元素的