【STL十九】算法——修改序列的操作(copy、move、remove、transform、replace)

news2024/11/30 20:48:15

算法——不修改序列的操作(copy、move、transform、remove、replace)

  • 一、分类
  • 二、修改序列的操作
  • 三、copy
  • 四、move
  • 五、remove、remove_if
  • 六、fill、transform、replace、replace_if、reverse

一、分类

根据网站https://www.apiref.com/cpp-zh/cpp/header.html显示,头文件<algorithm>提供的算法如下图。

  • 常用的分类
    • 不修改序列的操作
    • 修改序列的操作
    • 排序操作
    • 集合操作

在这里插入图片描述

  • 头文件
#include <algorithm>

二、修改序列的操作

项目Value
copy()将一系列元素复制到新位置。
copy_if()如果谓词对值返回true,则将一系列元素复制到新位置。
move()将某一范围的元素移动到一个新的位置
fill()将一个给定值复制赋值给一个范围内的每个元素
transform将一个函数应用于某一范围的各个元素,并在目标范围存储结果
remove()移除满足特定判别标准的元素
remove_if()移除满足特定判别标准的元素
replace将所有满足特定判别标准的值替换为另一个值
replace_if将所有满足特定判别标准的值替换为另一个值
reverse逆转范围中的元素顺序

三、copy

C++98
template <class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);

参数 (Parameters)
first - 将迭代器输入到序列中的初始位置。
last - 将迭代器输入到序列中的最终位置。
result - 将迭代器输出到新序列中的初始位置。
返回值
返回到目标范围末尾的迭代器,其中元素已被复制。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void) {
    vector<int> v1 = { 1, 2, 3, 4, 5 };
    vector<int> v2(5);
    copy(v1.begin(), v1.end(), v2.begin());
    cout << "Vector v2 contains following elements" << endl;
    for (auto it = v2.begin(); it != v2.end(); ++it)
        cout << *it << endl;
    return 0;
}

输出

Vector v2 contains following elements
1
2
3
4
5

  • copy_if() 算法可以从源序列复制使谓词返回 true 的元素,所以可以把它看作一个过滤器。前两个参数定义源序列的输入迭代器,第三个参数是指向目的序列的第一个位置的输出迭代器,第 4 个参数是一个谓词。会返回一个输出迭代器,它指向最后一个被复制元素的下一个位置。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool pre(int n) {
    return (n % 2 != 0);
};

int main(void) {
    vector<int> v1 = { 1, 2, 3, 4, 5 };
    vector<int> v2(3);
    copy_if(v1.begin(), v1.end(), v2.begin(), pre);
    cout << "Following are the Odd numbers from vector" << endl;
    for (auto it = v2.begin(); it != v2.end(); ++it)
        cout << *it << endl;
    return 0;
}

输出

Following are the Odd numbers from vector
1
3
5

四、move

  • move() 算法会将它的前两个输入迭代器参数指定的序列移到第三个参数定义的目的序列的开始位置,第三个参数必须是输出迭代器。这个算法返回的迭代器指向最后一个被移动到目的序列的元素的下一个位置。

  • 这是一个移动操作,因此无法保证在进行这个操作之后,输入序列仍然保持不变;源元素仍然会存在,但它们的值可能不再相同了,因此在移动之后,就不应该再使用它们。如果源序列可以被替换或破坏,就可以选择使用 move() 算法。如果不想扰乱源序列,可以使用 copy() 算法。

#include <iostream>
#include <vector>

using namespace std;

void test1()
{
    cout << "==============test1==============\n";
    std::vector<int> v1 = { 1,2,3 ,4,5 };
    std::vector<int> v2 = { 6,7,8 };

    // 建议的用法
    std::move(v1.begin(), v1.end(), std::back_inserter(v2));

    cout << "v1.size()=" << v1.size() << endl;
    cout << "v2.size()=" << v2.size() << endl;
    for (auto t : v2) std::cout << t;
    cout << endl;
    for (auto t : v1) std::cout << t;
}

void test2()
{
    cout << "\n==============test2==============\n";
    std::vector<int> v1 = { 1,2,3 ,4,5 };
    std::vector<int> v2 = { 6,7,8 };

    // 建议的用法
    v2 = std::move(v1);

    cout << "v1.size() = " << v1.size() << endl;
    cout << "v2.size() = " << v2.size() << endl;
    for (auto t : v2) std::cout << t;
}

void test3()
{
    cout << "\n==============test3==============\n";
    std::vector<int> v1 = { 1,2,3 };
    std::vector<int> v2 = { 6,7,8 ,9 };

    // 不建议使用,v1长度大于v2时,会报错的
    std::move(v1.begin(), v1.end(), v2.begin());

    cout << "v1.size() = " << v1.size() << endl;
    cout << "v2.size() = " << v2.size() << endl;
}

int main()
{
    test1();
    test2();
    test3();
}

输出

==============test1==============
v1.size()=5
v2.size()=8
67812345
12345
==============test2==============
v1.size() = 0
v2.size() = 5
12345
==============test3==============
v1.size() = 3
v2.size() = 4

#include <iostream>
#include <vector>
#include <list>
#include <iterator>
#include <thread>
#include <chrono>

void f(int n)
{
    std::this_thread::sleep_for(std::chrono::seconds(n));
    std::cout << "thread " << n << " ended" << '\n';
}

int main()
{
    std::vector<std::thread> v;
    v.emplace_back(f, 1);
    v.emplace_back(f, 2);
    v.emplace_back(f, 3);
    std::list<std::thread> l;
    // copy() 无法编译,因为 std::thread 不可复制

    std::move(v.begin(), v.end(), std::back_inserter(l));
    for (auto& t : l) t.join();
}

输出

thread 1 ended
thread 2 ended
thread 3 ended

五、remove、remove_if

移除操作不会改变被“移除”元素的序列的元素个数。
有 4 种移除算法:

  • remove() 可以从它的前两个正向迭代器参数指定的序列中移除和第三个参数相等的对象。基本上每个元素都是通过用它后面的元素覆盖它来实现移除的。它会返回一个指向新的最后一个元素之后的位置的迭代器。
    remove_if() 可以从前两个正向迭代器指定的序列中移除能够使作为第三个参数的谓词返回 true 的元素。
  • 官网的代码很好,大家可以分析下,很有意思的。
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
#include <string_view>

int main()
{
    std::string str1 = "Text with some   spaces";

    auto noSpaceEnd = std::remove(str1.begin(), str1.end(), ' ');

    // The spaces are removed from the string only logically.
    // Note, we use view, the original string is still not shrunk:
    std::cout << std::string_view(str1.begin(), noSpaceEnd)
        << " size: " << str1.size() << '\n';

    str1.erase(noSpaceEnd, str1.end());

    // The spaces are removed from the string physically.
    std::cout << str1 << " size: " << str1.size() << '\n';

    std::string str2 = "Text\n with\tsome \t  whitespaces\n\n";
    auto f = [](unsigned char x) { return std::isspace(x); };
    str2.erase(std::remove_if(str2.begin(),str2.end(), f),str2.end());
    std::cout << str2 << '\n';
}

输出

Textwithsomespaces size: 23
Textwithsomespaces size: 18
Textwithsomewhitespaces

六、fill、transform、replace、replace_if、reverse

#include <iostream>
#include <vector>
#include<string>
#include <algorithm>
#include <random>
using namespace std;

void test1()
{
    cout << "\n==============test1==============\n";

    vector<int> v(3);

    fill(v.begin(), v.end(), 1);
    for (auto it = v.begin(); it != v.end(); ++it)
        cout << *it << endl;
}

void test2()
{
    cout << "\n==============test2==============\n";
    std::vector<double> v1{ 20.0, 0.0, 3.2, 100.0 };
    std::vector<double> v2(v1.size());

    auto f = [](double temp) { return temp / 2 + 1; };
    std::transform(std::begin(v1), std::end(v1), std::rbegin(v2), f);

    for (auto it = v2.begin(); it != v2.end(); ++it)
        cout << *it << endl;
}

void test3()
{
    cout << "\n==============test3==============\n";
    std::vector<int> v{ 10, 11, 10, -6 };
    std::replace(std::begin(v), std::end(v), 10, 99);

    for (auto it = v.begin(); it != v.end(); ++it)
        cout << *it << endl;
}

void test4()
{
    cout << "\n==============test4==============\n";
    string str{ "This is a good choice !" };
    std::replace_if(std::begin(str), std::end(str), [](char ch) {return std::isspace(ch); }, '_');
    //Result:This_is_a_good_choice!

    cout << str;
}

void test5()
{
    cout << "\n==============test5==============\n";
    std::vector<int> v{ 1,2,3 };
    std::reverse(std::begin(v), std::end(v));
    for (auto e : v) std::cout << e;
}

int main(void) {
    test1();
    test2();
    test3();
    test4();
    test5();
    return 0;
}

输出

==============test1==============
1
1
1

==============test2==============
51
2.6
1
11

==============test3==============
99
11
99
-6

==============test4==============
This_is_a_good_choice_!
==============test5==============
321

参考
1、C++ STL 容器库 中文文档
2、STL教程:C++ STL快速入门
3、https://www.apiref.com/cpp-zh/cpp/header.html
4、https://en.cppreference.com/w/cpp/header
5、WIKI教程_C ++标准库_C++ Library - <algorithm>

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

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

相关文章

Spring的执行流程以及Bean的作用域和生命周期

深入Bean对象 1. Bean对象的作用域1.1 引出作用域问题1.2 六种作用域 2. Spring的执行流程3. Bean对象的生命周期 在之前的学习中&#xff0c;我们了解到Spring能够用来帮助我们管理Java中的Bean对象&#xff0c;我们能够向Spring的IOC容器中添加以及获取对象。那我们从Spring对…

【腾讯云 Finops Crane 集训营】学习云原生成本优化

目录 开篇介绍搭建环境第一步第二步第三步 添加集群成本洞察成本分析资源推荐与副本数智能预测与自动扩缩容EHPA安装Metrics Server创建测试应用创建 EffectiveHPA增加负载整体流程 调度优化负载感知调度拓扑感知调度 混部清理环境 开篇 某次闲逛CSDN&#xff0c;发现了这样一…

(文章复现)基于电力系统碳排放流理论的碳排放分摊模型研究(含matlab代码)

参考文献&#xff1a;基于电力系统碳排放流理论的碳排放分摊模型研究 之前写过一篇博客复现论文《电力系统碳排放流的计算方法初探》&#xff0c;那篇文章模型比较简单&#xff0c;没有考虑网损。(文章复现)电力系统碳排放流的计算方法初探(含matlab代码) 今天要复现的这篇文献…

1行命令本地部署 AgentGPT

本地部署 AgentGPT 部署 AgentGPT访问 AgentGPT 部署 AgentGPT 运行下面命令部署 AgentGPT&#xff0c;输入你的 OpenAI Key&#xff0c; git clone https://github.com/reworkd/AgentGPT.git; cd AgentGPT; ./setup.sh --docker访问 AgentGPT 使用浏览器打开 http://localh…

万得后端一面

目录 1.说说重载和重写2.内连接和外连接3.如果有一个任务来了&#xff0c;线程池怎么运行5.hashset怎么判断重复6.list和set说说7.说说有哪些list8.单例模式的饿汉式和懒汉式&#xff0c;怎么样可以防止反射。9.volatile关键字说说 1.说说重载和重写 1、重载发生在本类&#x…

MySQL创建索引时提示“Specified key was too long; max key length is 767 bytes”

MySQL创建索引时提示“Specified key was too long; max key length is 767 bytes” 问题描述 数据库RDS MySQL版在创建表索引时&#xff0c;出现如下错误信息。 Error 1071: Specified key was too long; max key length is 767 bytes.ERROR 1709 (HY000): Index column siz…

基于ESP32/ESP8266的单通道LoRaWAN网关设计-网页界面介绍

资料下载链接》》 网页界面介绍 对于单通道网关的第六版用户界面&#xff0c;我们专注于 Web 界面。本文档仅涉及 Web 界面。有几个部分要讨论&#xff1a; 用户界面说明web界面可以设置哪些参数单通道接口配置涉及的文件。 Web 界面的各个部分 启动 Web 界面时&#xff0…

【评测】腾讯云服务器的性能怎么样?

转载请注明出处&#xff1a;小锋学长生活大爆炸[ http://xfxuezhang.cn] 最近腾讯云推出了5年款服务器&#xff0c;性价比非常的高。但这么便宜的服务器&#xff0c;性能怎么样呢&#xff1f;学长特地领取了新人试用版测试了一下性能&#xff0c;这里与大家分享一下。 服务器领…

与对应负数同时存在的最大正整数

一、2441. 与对应负数同时存在的最大正整数 思路 这个题我想的是将数组中的负数全部找出来放进另一数组&#xff0c;然后再将原数组的元素与与之相比&#xff0c;如果相加等于0&#xff0c;那么就使num&#xff1b; 代码实现 int findMaxK(int* nums, int numsSize){int max0…

学系统集成项目管理工程师(中项)系列21b_整体管理(下)

1. 监控项目工作 1.1. 跟踪、审查和报告项目进展&#xff0c;以实现项目管理计划中确定的绩效目标的过程 1.2. 输入 1.2.1. 项目管理计划 1.2.2. 进度预测 1.2.2.1. 基于实际进展与进度基准的比较而计算出进度预测 1.2.2.1.1. 完工尚需时间估算(ETC) 1.2.2.1.2. 进度偏差(SV…

威胁报告检测到物理后果呈指数增长的OT网络攻击

2023年威胁报告 - 具有物理后果的 OT 网络攻击 在过去一年&#xff08;2022 年&#xff09;&#xff0c;我们看到了 57 起针对工业系统的 OT 相关网络攻击&#xff0c;这些攻击在现实世界中造成了物理后果。这是我们在 2021 年看到的 22 次类似攻击的 2.5 倍多&#xff0c;是 …

网路通信-路由交换协议

目录 一、什么是协议 二、为什么要有协议 三、协议分类 &#xff08;1&#xff09;OSI通信模型 &#xff08;2&#xff09;tcp/ip通信模型 &#xff08;3&#xff09;数据传输的过程 1.传输路线 2.发送者封装数据 3.数据经过交换机 4.数据经过路由器 5.路由器转发到目…

深度学习环境配置系列文章(四):WSL2配置Windows11和Linux双系统

深度学习环境配置系列文章目录 第一章 专业名称和配置方案介绍 第二章 Anaconda配置Python和PyTorch 第三章 配置VS Code和Jupyter的Python环境 第四章 WSL2配置Windows11和Linux双系统 第五章 配置Docker深度学习开发环境 第四章文章目录 深度学习环境配置系列文章目录前言一…

横截面收益率(二) 阿尔法策略是如何构建的

资本资产定价模型自从首次被提出以来在金融经济学中一直处于中心地位。 在一系列简化假定条件下&#xff0c;资本资产定价模型表明&#xff0c;任何证券的收益率与该证券 的系统性风险&#xff08;或者贝塔值&#xff09;呈线性关系。因此&#xff0c;依据资本资产定价模型横截…

【STM32】基础知识 第十三课 中断

【STM32】基础知识 第十三课 中断 概述中断是什么中断的作用 & 意义STM32 中断体系NVIC中断向量表STM32 中断优先级基本概念 STM32 外部中断器 (EXTI)EXTI 简介EXTI 配置 AFIOAFIO 与中断 案例 概述 今天小白我将带领大家详细介绍 STM32 单片机中的中断处理机制, 包括中断…

Python每日一练(20230514) 不同路径 I\II\III UniquePaths

目录 1. 不同路径 I Unique Paths 1 2. 不同路径 II Unique Paths 2 3. 不同路径 III Unique Paths 3 &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 不同路径 I Unique Paths 1 一个…

Java每日一练(20230514) 滑动窗、最大子序和、转罗马数字

目录 1. 滑动窗口最大值 &#x1f31f;&#x1f31f; 2. 最大子序和 &#x1f31f; 3. 整数转罗马数字 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1.…

C/C++每日一练(20230514) 全排列、分数转小数、排序链表去重II

目录 1. 全排列 &#x1f31f;&#x1f31f; 2. 分数到小数 &#x1f31f;&#x1f31f; 3. 删除排序链表中的重复元素 II &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Ja…

【C++】unordered_map与unordered_set(系列关联式容器)

文章目录 1.unordered系列关联式容器2. unordered_map3.unordered_set 1.unordered系列关联式容器 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;如map和set&#xff0c;它们在查询时效率可达logN&#xff0c;即最差情况下需要比较红黑树的高度…

【UnavailableInvalidChannel: The channel is not accessible or is invalid.】

Collecting package metadata (current_repodata.json): failedUnavailableInvalidChannel: The channel is not accessible or is invalid.channel name: simplechannel url: http://pypi.douban.com/simpleerror code: 404.condarc以点开头&#xff0c;一般表示 conda 应用程…