Day 31 C++ STL常用算法(下)

文章目录

  • 常用拷贝和替换算法
      • copy——容器内指定范围的元素拷贝到另一容器中
          • 函数原型
          • 注意——利用copy算法在拷贝时,目标容器要提前开辟空间
          • 示例
      • replace——将容器内指定范围的第一个旧元素修改为新元素
          • 函数原型
          • 注意——replace只会替换区间内满足条件的第一个旧元素
          • 示例
      • replace_if——在指定范围内将所有旧元素修改为新元素
          • 函数原型
          • 注意——replace会替换区间内满足条件的所有旧元素
      • swap——互换两个容器的元素
          • 函数原型
          • 注意——swap交换容器时,注意交换的容器要同种类型
            • 类型要匹配
            • 容器的状态
            • 迭代器的失效
            • 容器的大小和内存开销
            • 异常安全性
          • 示例
  • 常用算术生成算法
      • 注意——算术生成算法属于小型算法,使用时包含的头文件为 `#include <numeric>`
      • accumulate—— 计算区间内容器元素累计总和
          • 函数原型
          • 注意——如果容器为空,而且没有提供起始值参数,则调用accumulate函数会导致未定义行为
          • 示例
      • fill——用于将指定范围内的元素都设置为给定的值
          • 函数原型
          • 注意——fill函数会将指点范围内所有元素都填充为给定的值,原本已的值会被覆盖。
          • 示例
  • 常用集合算法
      • set_intersection——求两个容器的交集
          • 函数原型
          • 总结
      • set_union——求两个集合的并集
          • 函数原型
          • 总结(和set_intersection差不多)
          • 示例
      • set_difference——求两个集合的差集
          • 函数原型
          • 总结(都差不多)

常用拷贝和替换算法

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

函数原型
  • copy(iterator beg, iterator end, iterator dest);

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

    // beg 开始迭代器

    // end 结束迭代器

    // dest 目标起始迭代器

注意——利用copy算法在拷贝时,目标容器要提前开辟空间
示例
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> source {1, 2, 3, 4, 5};std::vector<int> destination(5);  // 提前开辟目标容器空间std::copy(source.begin(), source.end(), destination.begin());// 输出目标容器中的内容for (auto i : destination) {std::cout << i << " ";}std::cout << std::endl;return 0;
}

输出结果为:1 2 3 4 5

在上面的示例中,我们首先创建了一个源容器source,其中包含了一些整数。然后,我们创建了一个与源容器相同大小的目标容器destination,并且提前开辟了空间。

接下来,我们使用std::copy算法将源容器中的元素拷贝到目标容器中。通过传递源容器的迭代器source.begin()和source.end()以及目标容器的起始迭代器destination.begin()作为参数,实现了拷贝操作。

最后,遍历目标容器,并打印其中的元素

replace——将容器内指定范围的第一个旧元素修改为新元素

函数原型
  • replace(iterator beg, iterator end, oldvalue, newvalue);

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

    // beg 开始迭代器

    // end 结束迭代器

    // oldvalue 旧元素

    // newvalue 新元素

注意——replace只会替换区间内满足条件的第一个旧元素
示例
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec {1, 2, 3, 4, 5};std::replace(vec.begin(), vec.end(), 3, 9);// 输出修改后的容器内容for (auto i : vec) {std::cout << i << " ";}std::cout << std::endl;return 0;
}

输出结果为:
1 2 9 4 5

在上面的示例中,我们首先创建了一个整数向量vec,其中包含了一些整数。然后,我们使用std::replace算法将容器中的旧元素3替换为新元素9。

通过传递容器的起始迭代器vec.begin()和结束迭代器vec.end()作为参数,以及要替换的旧元素3和新元素9,实现了替换操作。

最后,我们遍历容器,并打印其中的元素,可以看到被替换的元素已经被修改为新元素。

replace_if——在指定范围内将所有旧元素修改为新元素

函数原型
  • **replace_if(iterator beg, iterator end, _pred, newvalue); **

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

    // beg 开始迭代器

    // end 结束迭代器

    // _pred 谓词,谓词函数是一个返回布尔值的函数,用于确定元素是否满足某个条件。

    // 注意谓语是返回bool的仿函数,是谓词,是一个类,不是函数,但是可以当函数用
    // 因此可以利用仿函数灵活筛选满足的条件

    // newvalue 替换的新元素

注意——replace会替换区间内满足条件的所有旧元素

示例:

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec {1, 2, 3, 4, 5};std::replace_if(vec.begin(), vec.end(), [](int num){ return num == 3; }, 9);// 输出修改后的容器内容for (auto i : vec) {std::cout << i << " ";}std::cout << std::endl;return 0;
}

输出结果为:
1 2 9 4 5

在这个示例中,我们使用了一个匿名的lambda函数作为谓词函数来判断元素是否需要被替换。lambda函数接受一个整数参数num,并返回一个bool值,判断这个整数是否等于3。如果等于3,则将其替换为新元素9。

通过使用lambda函数作为谓词函数,我们可以自定义替换的条件。在上述示例中,我们使用等于3的元素作为替换的条件。

需要注意的是,replace_if函数只会替换满足条件的第一个元素,如果想要替换所有满足条件的元素,可以考虑使用std::replace_copy_if或自定义循环进行处理。

swap——互换两个容器的元素

函数原型
  • swap(container c1, container c2);

    // 互换两个容器的元素

    // c1容器1

    // c2容器2

注意——swap交换容器时,注意交换的容器要同种类型

交换不同类型的容器,将会导致编译错误。

类型要匹配

要交换的容器类型要相同,或者满足可以进行隐式转换的条件。例如,两个 std::vector<int> 可以直接交换,但是 std::vector<int>std::vector<double> 之间不能直接交换。

容器的状态

交换容器时,要确保容器处于有效状态,即它们不应被移动、释放或销毁。否则,交换操作可能会导致未定义行为。

迭代器的失效

交换容器后,原来容器中的迭代器将会失效。如果有其他依赖于这些迭代器的代码,则需要谨慎处理,避免使用失效的迭代器。

容器的大小和内存开销

交换容器实际上是交换了它们的内部数据结构,这意味着会涉及到元素的复制或移动操作。如果容器的大小较大,交换操作可能会带来显著的内存开销和性能损失。

异常安全性

交换容器可能会引发异常,因此在交换操作之前,要考虑异常安全性,采取适当的措施来处理异常,以确保程序能够正常执行。

示例
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec1 {1, 2, 3};std::vector<int> vec2 {4, 5, 6};swap(vec1, vec2);// 输出交换后的vec1std::cout << "vec1: ";for (auto i : vec1) {std::cout << i << " ";}std::cout << std::endl;// 输出交换后的vec2std::cout << "vec2: ";for (auto i : vec2) {std::cout << i << " ";}std::cout << std::endl;return 0;
}

输出结果为:
vec1: 4 5 6
vec2: 1 2 3

在这个示例中,我们创建了两个vector类型的容器vec1和vec2。
然后,通过调用swap函数来交换这两个容器的元素。最
终,vec1中的元素变成了4, 5, 6,vec2中的元素变成了1, 2, 3。

常用算术生成算法

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

accumulate—— 计算区间内容器元素累计总和

函数原型
  • accumulate(iterator beg, iterator end, value);

    // 计算容器元素累计总和

    // beg 开始迭代器

    // end 结束迭代器

    // value 起始值
    //起始值value是可选的,如果不提供该参数,那么默认起始值将是容器中的第一个元素的值。(看下面例子)

注意——如果容器为空,而且没有提供起始值参数,则调用accumulate函数会导致未定义行为

所以,在使用accumulate函数时,建议在累加之前检查容器是否非空,或者提供一个明确的起始值参数。

示例
#include <iostream>
#include <vector>
#include <numeric>int main() {std::vector<int> vec {1, 2, 3, 4, 5};int sum = std::accumulate(vec.begin(), vec.end());std::cout << "Sum: " << sum << std::endl;return 0;
}

输出结果为:
Sum: 15

在这个示例中,我们调用了accumulate函数来计算容器vec中元素的累计总和,但没有提供起始值参数。由于没有指定起始值,accumulate函数会使用容器中的第一个元素作为起始值进行累加运算。

因此,根据示例中的容器vec,累计总和仍然是15。

fill——用于将指定范围内的元素都设置为给定的值

函数原型
  • fill(iterator beg, iterator end, value);

    // 向容器中填充元素

    // beg 开始迭代器

    // end 结束迭代器

    // value 填充的值

注意——fill函数会将指点范围内所有元素都填充为给定的值,原本已的值会被覆盖。
示例
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec {1, 2, 3, 4, 5};std::fill(vec.begin(), vec.end(), 10);// 输出填充后的向量std::cout << "Filled Vector: ";for (auto i : vec) {std::cout << i << " ";}std::cout << std::endl;return 0;
}

输出结果为:

Filled Vector: 10 10 10 10 10
在这个示例中,我们有一个包含初始值的向量vec,其中包含了数字1到5。然后,我们使用fill函数将容器vec中的所有元素都填充为10。

最终的输出结果显示,原本向量中的元素已经被覆盖,全部变成了10, 10, 10, 10, 10。

因此,需要注意,在使用fill函数时,如果你希望保留原有元素的值,只填充指定范围内的部分元素,可以使用更具灵活性的方法,如迭代器和算法结合使用来实现部分填充。

常用集合算法

set_intersection——求两个容器的交集

set_intersection 函数通常用于计算两个有序集合的交集。
但是,它实际上可以用于任何支持随机访问的序列容器,而不仅限于集合。

函数原型
  • set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
    // beg1 容器1开始迭代器
    // end1 容器1结束迭代器
    // beg2 容器2开始迭代器
    // end2 容器2结束迭代器
    // dest 目标容器开始迭代器
总结
  • 求交集的两个集合必须是有序序列
  • 目标容器开辟空间需要从两个容器中取小值
  • set_intersection返回值既是交集中最后一个元素的位置

示例:

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec1 {1, 2, 3, 4, 5};std::vector<int> vec2 {3, 4, 5, 6, 7};std::vector<int> intersection(std::min(vec1.size(), vec2.size()));auto it = std::set_intersection(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), intersection.begin());// 输出交集中的元素std::cout << "Intersection: ";for (auto i = intersection.begin(); i != it; ++i) {std::cout << *i << " ";}std::cout << std::endl;return 0;
}

输出结果为:
Intersection: 3 4 5

在这个示例中,我们有两个有序的向量vec1和vec2,分别包含了不同的整数。我们需要找出这两个向量的交集。

首先,我们创建了一个目标容器intersection,它的大小为两个输入容器中较小的那个。

然后,使用set_intersection函数将两个输入容器中的交集复制到目标容器intersection中。set_intersection函数接受五个参数,分别是两个输入容器的起始和结束迭代器,以及目标容器的起始迭代器。这样,交集中的元素就会复制到目标容器中。

最后,我们遍历目标容器中的元素,并输出交集中的值。

set_union——求两个集合的并集

函数原型
  • set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

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

总结(和set_intersection差不多)
  • 求并集的两个集合必须的有序序列
  • 目标容器开辟空间需要两个容器相加
  • set_union返回值既是并集中最后一个元素的位置
示例
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec1 {1, 2, 3, 4, 5};std::vector<int> vec2 {3, 4, 5, 6, 7};std::vector<int> unionSet(vec1.size() + vec2.size());auto it = std::set_union(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), unionSet.begin());// 输出并集中的元素std::cout << "Union: ";for (auto i = unionSet.begin(); i != it; ++i) {std::cout << *i << " ";}std::cout << std::endl;return 0;
}

输出结果为:
Union: 1 2 3 4 5 6 7

在这个示例中,我们有两个有序的向量vec1和vec2,分别包含了不同的整数。我们需要找出这两个向量的并集。

首先,我们创建了一个目标容器unionSet,它的大小为两个输入容器的总大小。

然后,使用set_union函数将两个输入容器中的并集复制到目标容器unionSet中。
set_union函数接受五个参数,分别是两个输入容器的起始和结束迭代器,以及目标容器的起始迭代器。这样,并集中的元素就会复制到目标容器中。

最后,我们遍历目标容器中的元素,并输出并集中的值。

set_difference——求两个集合的差集

函数原型
  • set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);

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

总结(都差不多)
  • 求差集的两个集合必须的有序序列
  • 目标容器开辟空间需要从两个容器取较大值
  • set_difference返回值既是差集中最后一个元素的位置

示例:

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec1 {1, 2, 3, 4, 5};std::vector<int> vec2 {3, 4, 5, 6, 7};std::vector<int> difference(std::max(vec1.size(), vec2.size()));auto it = std::set_difference(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), difference.begin());// 输出差集中的元素std::cout << "Difference: ";for (auto i = difference.begin(); i != it; ++i) {std::cout << *i << " ";}std::cout << std::endl;return 0;
}

输出结果为:
Difference: 1 2

在这个示例中,我们有两个有序的向量vec1和vec2,分别包含了不同的整数。我们需要找出这两个向量的差集。

首先,我们创建了一个目标容器difference,它的大小为两个输入容器中较大的那个。

然后,使用set_difference函数将两个输入容器中的差集复制到目标容器difference中。
set_difference函数接受五个参数,分别是两个输入容器的起始和结束迭代器,以及目标容器的起始迭代器。这样,差集中的元素就会复制到目标容器中。

最后,我们遍历目标容器中的元素,并输出差集中的值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/40945.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cve-2016-7193:wwlib 模块堆数据结构溢出

简介 漏洞编号&#xff1a;cve-2016-7193漏洞类型&#xff1a;堆溢出软件名称&#xff1a;Office模块名称&#xff1a;wwlib历史漏洞&#xff1a;较多影响的版本 攻击利用&#xff1a;APT 攻击利器-Word 漏洞 CVE-2016-7193 原理揭秘 操作环境 系统&#xff1a;Win10 1607软…

C++ 动态内存

C 动态内存 C 程序中的内存分为两个部分&#xff1a; 栈&#xff1a;在函数内部声明的所有变量都将占用栈内存堆&#xff1a;这是程序中未使用的内存&#xff0c;在程序运行时可用于动态分配内存 很多时候&#xff0c;无法提前预知需要多少内存来存储某个定义变量中的特定信…

【Docker报错】docker拉取镜像时报错:no such host

报错信息 [rootSoft soft]# docker pull mysql Using default tag: latest Error response from daemon: Head "https://registry-1.docker.io/v2/library/mysql/manifests/latest": dial tcp: lookup registry-1.docker.io on 192.168.80.2:53: no such host解决方法…

3D模型格式转换工具如何与Parasolid集成?

概述 HOOPS Exchange包括一个 Parasolid 连接器&#xff0c;它允许 Parasolid 开发人员轻松地将 CAD 数据导入到活动的 Parasolid 会话中。如果源数据基于 Parasolid&#xff08;NX、Solid Edge 或 SolidWorks&#xff09;&#xff0c;则数据将按原样导入。 这意味着您可以假…

主数据管理案例-某政务

1、 背景介绍及难点分析 近年来&#xff0c;我国在大数据发展方面持续发力&#xff0c;取得了明显成效。但也要看到&#xff0c;目前我国大数据发展还存在“孤岛化”“碎片化”等问题&#xff0c;无序参与过度与创新参与不足并存&#xff0c;导致大数据资源配置统筹不&#xff…

【C++】list容器

1.list基本概念 2.list构造函数 #include <iostream> using namespace std;#include<list> //链表list容器构造函数//输出list链表 void printList(const list<int>& L) {for (list<int>::const_iterator it L.begin(); it ! L.end(); it){cout &…

STM32入门学习之定时器PWM输出

1.脉冲宽度调制PWM(Pulse Width Modulation)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM可以理解为高低电平的占空比&#xff0c;即输出高电平时间与低电平时间的比值。PWM的应用是否广泛&#xff0c;比如在步进电机的控制中&#xff0c;可以通过P…

【MySQL系列】-回表、覆盖索引真的懂吗

【MySQL系列】-回表、覆盖索引真的懂吗 文章目录 【MySQL系列】-回表、覆盖索引真的懂吗一、MYSQL索引结构1.1 索引的概念1.2 索引的特点1.3 索引的优点1.4 索引的缺点 二、B-Tree与BTree2.1 B-Tree2.2 BTree2.3 B-Tree 与BTree树的区别2.4 那么为什么InnoDB的主键最好要搞成有…

记一次 .NET 某外贸ERP 内存暴涨分析

一&#xff1a;背景 1. 讲故事 上周有位朋友找到我&#xff0c;说他的 API 被多次调用后出现了内存暴涨&#xff0c;让我帮忙看下是怎么回事&#xff1f;看样子是有些担心&#xff0c;但也不是特别担心&#xff0c;那既然找到我&#xff0c;就给他分析一下吧。 二&#xff1…

【软件测试】接口测试工具APIpost

说实话&#xff0c;了解APIpost是因为&#xff0c;我的所有接口相关的文章下&#xff0c;都有该APIpost水军的评论&#xff0c;无非就是APIpost是中文版的postman&#xff0c;有多么多么好用&#xff0c;虽然咱也还不是什么啥网红&#xff0c;但是不知会一声就乱在评论区打广告…

【力扣每日一题】2023.8.14 合并二叉树

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 给我们合并两棵二叉树&#xff0c;合并的方式就是把对应位置的节点的值相加&#xff0c;最后把合并后的二叉树的根节点返回出去。 这类二…

You have docker-compose v1 installed, but we require Docker Compose v2.

curl -SL https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose chmod x /usr/local/bin/docker-compose docker-compose --version

一文看尽R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD详解

一文看尽R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD详解 以下六篇文章总结详细&#xff1a; 1. 一文读懂目标检测&#xff1a;R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD 2. 【深度学习】R-CNN 论文解读及个人理解 3、R-CNN论文详解 4、一文读懂Faster RCNN 5、学一百遍都…

JAVA基础知识(六)——异常处理

异常 一、异常概述与异常体系结构二、常见异常三、异常处理机制一&#xff1a;try-catch-finally四、异常处理机制二&#xff1a;throws五、手动抛出异常&#xff1a;throw六、用户自定义异常类七、开发中如何选择使用try-catch-finally还是使用throws八、如何看待代码中的编译…

goland插件推荐Rider UI Theme Pack

推荐一个goland配色插件Rider UI Theme Pack&#xff0c;里面自带visual assist配色&#xff0c;配色截图如下&#xff1a; 直接在plugins里面进行搜索或者在插件home page下载后进行安装&#xff0c; 然后按照下图进行设置即可。 此插件还适用于Jetbrains旗下的Clion和Pycharm…

WX1860- ngbe-1.2.5 xdp程序在路由模式下,使用iperf工具测试数据包不转发,用jmeter可以

本地验证时重定向iperf包有出现calltrace错误&#xff0c;经推断&#xff0c;系统PAGE_SIZE<8k时可能出现&#xff08;getconf PAGE_SIZE指令可查看&#xff09;&#xff0c;按下图将ngbe_main.c的2350行ngbe_rx_bufsz改为ngbe_rx_pg_size可修复。其次&#xff0c;需要将加载…

鸿蒙3.1 基于Token的访问控制

介绍 代码路径:security_access_token: ATM(AccessTokenManager)是OpenHarmony上基于AccessToken构建的统一的应用权限管理能力。 ATM(AccessTokenManager)是OpenHarmony上基于AccessToken构建的统一的应用权限管理能力。 应用的Accesstoken信息主要包括应用身份标识APPID、…

什么是游戏出海运营?

游戏出海运营&#xff0c;也称为游戏海外运营&#xff0c;是指将原本面向国内市场的游戏产品拓展到国际市场&#xff0c;以在海外地区推广、发行、运营游戏的过程。这涵盖了从市场调研、产品适应性优化、本地化翻译、推广营销、社区互动到客户支持等一系列策略和活动&#xff0…

阿里云对象存储服务OSS

1、引依赖 <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version> </dependency> <dependency><groupId>javax.xml.bind</groupId><artifa…

Mocha and Red and Blue

一、题目 题面翻译 给定长为 n n n 的仅由 R \texttt{R} R、 B \texttt{B} B、 ? \texttt{?} ? 组成的字符串 S S S&#xff0c;请你在 ? \texttt{?} ? 处填入 R \texttt{R} R 或 B \texttt{B} B&#xff0c;使得相邻位置字符相同的数量最少。 译者 ajthreac 题…