【STL十八】算法——不修改序列的操作(for_each、count、find、equal、search)

news2024/12/24 10:08:48

【STL十八】算法——不修改序列的操作(for_each、count、find、equal、search)

  • 一、简介
  • 二、头文件
  • 三、分类
  • 四、不修改序列的操作
    • 1、for_each
    • 2、count、count_if
    • 3、find、find_if
    • 4、euqal
    • 5、search

  • 前言:在前面我们讲解容器和函数对象时,都刻意的回避了算法,在此,我们单独分一篇文章,来讲解下stl提供的算法。

一、简介

STL算法部分主要是由三个头文件承担: algorithm、numeric、functional

  • algorithm:意思是算法,只要想使用STL库中的算法函数就得包含该头文件。
  • numeric:包含了一系列用于计算数值序列的算法,其具有一定的灵活性,也能够适用于部分非数值序列的计算
  • functional:定义了一些模板,可以用来声明函数对象。

本文,我们讲解下algorithm提供的算法。

二、头文件

#include <algorithm>

三、分类

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

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

在这里插入图片描述

四、不修改序列的操作

项目Value
for_each()在范围的每个元素上应用提供的函数。
count()返回范围内值的出现次数。
count_if()返回满足条件的范围的值的出现次数。
find()查找元素的第一个匹配项。
find_if()查找满足条件的元素的第一个匹配项。
equal()测试两组元素是否相等。 两组的大小不必相等。
search()用于在序列 A 中查找序列 B 第一次出现的位置。

1、for_each

for_each在容器中的使用

  • 普通函数
  • 仿函数(函数对象)
  • lambda表达式
// C++98
template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function fn);

参数 (Parameters)
first - 将迭代器输入到初始位置。
last - 最终位置的最终迭代器。
fn - 接受范围内元素作为参数的一元函数。


返回值
返回函数fn 。

  • demo
// for_each example
#include <iostream> 
#include <algorithm>  
#include <vector>  

// 普通函数
void myfunction(int i) { 
	std::cout << ' ' << i;
}

// 函数对象
class FunctionObject {  
public:
	void operator() (int i) 
	{ 
		std::cout << ' ' << i; 
	}
} ;

// lamdba表达式
auto f = [](int i)
{
	std::cout << ' ' << i;
};

int main() {
	std::vector<int> myvector = {1,3,5};

	//给 for_each 传递一个函数
	std::cout << "myvector contains:";
	for_each(myvector.begin(), myvector.end(), myfunction);  
	std::cout << '\n';

	//给 for_each 传递一个函数对象
	std::cout << "myvector contains:";
	FunctionObject fo;
	for_each(myvector.begin(), myvector.end(), fo);  
	std::cout << '\n';

	// 给 for_each 传递一个lamdba
	std::cout << "myvector contains:";
	for_each(myvector.begin(), myvector.end(), f); 
	std::cout << '\n';

	return 0;
}

输出

myvector contains: 1 3 5
myvector contains: 1 3 5
myvector contains: 1 3 5

2、count、count_if

  • count
//C++98
template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count (InputIterator first, InputIterator last, const T& val);

参数 (Parameters)
first - 将迭代器输入到搜索序列的初始位置。
last - 将迭代器输入到搜索序列的最终位置。
val - 要在范围内搜索的值。


返回值
返回第一个到最后一个范围内的元素数。

  • count_if
// C++98
template <class InputIterator, class Predicate>
typename iterator_traits<InputIterator>::difference_type
count_if (InputIterator first, InputIterator last, UnaryPredicate pred);

参数 (Parameters)
first - 将迭代器输入到搜索序列的初始位置。
last - 将迭代器输入到搜索序列的最终位置。
pred - 一元谓词,它接受一个参数并返回bool。


返回值
返回pred返回true的范围内的元素数。

  • demo
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool mygreater(int n) {
	return (n > 3);
}

int main(void) {
	vector<int> v = { 1, 3, 3, 3, 3 , 4, 5};

	// count
	int cnt;
	cnt = count(v.begin(), v.end(), 3);
	cout << "Number 3 occurs " << cnt << " times." << endl;

	// count_if
	int cnt2;
	cnt2 = count_if(v.begin(), v.end(), mygreater);
	cout << "There are " << cnt2 << " numbers are greater that 3." << endl;
	
	return 0;
}

输出

Number 3 occurs 4 times.
There are 2 numbers are greater that 3.

3、find、find_if

  • 模板及参数请参考cout、count_if
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

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

int main(void) {
    int val = 5;
    vector<int> v = { 1, 2, 3, 4, 5 };
    auto result = find(v.begin(), v.end(), val);
    if (result != end(v))
        cout << "Vector contains element " << val << endl;
    
    auto it = find_if(v.begin(), v.end(), unary_pre);
    if (it != end(v))
        cout << "First even number is " << *it << endl;

    return 0;
}

输出

Vector contains element 5
First even number is 2

4、euqal

  • 3 个输入迭代器参数,前两个参数是第一个序列的开始和结束迭代器,第三个参数是第二个序列的开始迭代器。
  • 如果第二个序列中包含的元素少于第一个序列,结果是未定义的。 第2个长度要大于第1个的。
  • 4 个参数:第一个序列的开始和结束迭代器,第二个序列的开始和结束迭代器,如果两个序列的长度不同,那么结果总是为 false。本节会演示这两个版本,但推荐使用接受 4 个参数的版本,因为它不会产生未定义的行为。
  • demo
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void) {
    vector<int> v1 = { 1, 2, 3, 4, 5 };
    vector<int> v2 = { 2, 3, 4, 5, 6};

    bool result;
    result = equal(v1.begin(), v1.end(), v2.begin());
    if (result == false)
        cout << "Vector range is not equal." << endl;

    result = equal(v1.begin()+1, v1.end(), v2.begin());
    if (result == true)
        cout << "Vector range is equal." << endl;

    result = equal(v1.begin() + 1, v1.end(), v2.begin(),v2.end());
    if (result == false)
        cout << "Vector range is not equal." << endl;

    result = equal(v1.begin() + 1, v1.end(), v2.begin(), v2.end()-1);
    if (result == true)
        cout << "Vector range is equal." << endl;
    return 0;
}

输出

Vector range is not equal.
Vector range is equal.
Vector range is not equal.
Vector range is equal.

  • 第1条语句中,两个序列的第一个元素直接就不匹配,所以结果为 false。
  • 第 2条语句的输出为 true,因为 v1 的第二个元素到最后一个元素都从 v2 的第一个元素开始匹配。第二个序列的元素个数比第一个序列的元素个数多 1,但 第一个序列的元素个数决定了比较多少个对应的元素。
  • 第3条语句的输出为 false,因为序列是不同的。这条语句不同于前面的 equal() 调用,因为指定了第二个序列的结束迭代器。
  • 第4 条语句会从 v1 的第二个元素开始,与 v2 从第一个元素开始比较相同个数的元素,所以输出为 true。

5、search

  • find_end() 函数用于在序列 A 中查找序列 B 最后一次出现的位置。那么,如果想知道序列 B 在序列 A 中第一次出现的位置,该如何实现呢?可以借助 search() 函数。

  • search() 函数其功能恰好和 find_end() 函数相反,用于在序列 A 中查找序列 B 第一次出现的位置

#include <iostream> 
#include <vector> 
#include <algorithm> 
using namespace std;
int main()
{
    int i, j;

    // Declaring the sequence to be searched into 
    vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7 };

    // Declaring the subsequence to be searched for 
    vector<int> v2 = { 3, 4, 5 };

    // Declaring an iterator for storing the returning pointer 
    vector<int>::iterator i1;

    // Using std::search and storing the result in 
    // iterator i1 
    i1 = std::search(v1.begin(), v1.end(), v2.begin(), v2.end());

    // checking if iterator i1 contains end pointer of v1 or not 
    if (i1 != v1.end()) {
        cout << "vector2 is present at index " << (i1 - v1.begin()) << endl;
    }
    else {
        cout << "vector2 is not present in vector1" << endl;
    }


    // Declaring the subsequence to be searched for 
    vector<int> v3 = { 3, 4, 6 };
    vector<int>::iterator i2;
    i2 = std::search(v1.begin(), v1.end(), v3.begin(), v3.end());
    if (i2 != v1.end()) {
        cout << "vector3 is present at index " << (i2 - v1.begin()) << endl;
    }
    else {
        cout << "vector3 is not present in vector1" << endl;
    }

    return 0;
}

输出

vector2 is present at index 2
vector3 is not present in vector1

  • 也可以使用函数对象;(二元谓词)
#include <iostream> 
#include <vector> 
#include <algorithm> 
using namespace std;

// Defining the BinaryPredicate function 
bool pred(int i, int j)
{
    cout << i << ";" << j<< endl;
    if (i > j) {
        return 1;
        
    }
    else {
        return 0;
    }
}

int main()
{
    int i, j;

    // Declaring the sequence to be searched into 
    vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    // Declaring the subsequence to be compared to based 
    // on predicate 
    vector<int> v2 = { 2, 3, 6 };

    // Declaring an iterator for storing the returning pointer 
    vector<int>::iterator i1;

    // Using std::search and storing the result in 
    // iterator i1 based on predicate pred 
    i1 = std::search(v1.begin(), v1.end(), v2.begin(), v2.end(), pred);

    cout << *i1 <<endl;

    // checking if iterator i1 contains end pointer of v1 or not 
    if (i1 != v1.end()) {
        cout << "vector1 elements are greater than vector2 starting "
            << "from position " << (i1 - v1.begin());
    }
    else {
        cout << "vector1 elements are not greater than vector2 "
            << "elements consecutively.";
    }

    return 0;
}

输出

1;2
2;2
3;2
4;3
5;6
4;2
5;3
6;6
5;2
6;3
7;6
5
vector1 elements are greater than vector2 starting from position 4

说明

  • vector,v1中的{5,6,7},第一次出现比v2中的{ 2, 3, 6 }大

参考
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/509007.html

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

相关文章

X.25,帧中继(FR),ATM三种分组交换系统

X.25、帧中继&#xff08;FR&#xff09;、ATM 是流行的三种分组交换系统&#xff0c;它们具有不同的特点。 两个术语&#xff1a; DTE(Data Terminal Equipment) &#xff0c;数据终端设备&#xff0c;如我们的个人电脑、手机。 DCE(Data Circuit Equipment) &#xff0c;数据…

【STM32】基础知识 第十二课 GPIO

【STM32】基础知识 第十二课 GPIO 概述GPIO 简介GPIO 模式GPIO 特点GPIO 配置GPIO 操作施密特触发器案例 概述 本文小白我将来介绍通用输入与输出, GPIO (General-Purpose Input/Output) 在单片机中的应用, 以及如何配合和食用 GPIO 来实现各种功能. GPIO 简介 GPIO 是单片机…

十三、共享内存

文章目录 一、什么是共享内存&#xff08;一&#xff09;共享内存的定义&#xff08;二&#xff09;共享内存的原理&#xff08;三&#xff09;共享内存的理解 二、为什么要有共享内存三、共享内存怎么进行&#xff08;一&#xff09; 共享内存的数据结构&#xff08;二&#x…

【Redis系列】Redis布隆过滤之8亿大数据集实战

序言 即便平凡的日子仿佛毫无波澜&#xff0c;但在某个特定的时刻&#xff0c;执着的努力便会显现出它的价值和意义。 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记一级重要蓝色&#xff1a;用来标记二级重要 …

SPC Control Chart Tools for WPF 3.1 Crack

使用 WPF 的 SPC 控制图工具&#xff0c;将变量控制图&#xff08;X-Bar R、X-Bar Sigma、单个范围、中值范围、EWMA、MA、MAMR、MAMS 和 CuSum 控制图&#xff09;、属性控制图&#xff08;p、np、c、u 和 DPMO 控制图&#xff09;、频率直方图和帕累托图添加到 WPF 和 WPF We…

物理机:显卡3080 环境Centos7.9 如何检查及安装显卡驱动

环境&#xff1a; 硬件服务器&#xff1a;I5处理器&#xff0c; 显卡&#xff1a;3080 12G 等。 目标&#xff1a; 测试是否安装显卡。 如何找到正确的驱动版本。 安装显卡正确的显卡驱动。 一、检查是否正确安装显卡&#xff1a; # 检查使用什么型号的显卡&#xff1a; yum…

淄博烧烤,怎么就“出圈”了-也是机器视觉行业职场中的态度:少一点套路,多一些真诚,少一点计较,多一些宽容

我认为淄博烧烤之所以火爆&#xff0c;是因为它代表了一种淄博人的态度&#xff0c;一种对生活的热爱和对客人的真诚。 我认为淄博烧烤之所以火爆&#xff0c;是因为它代表了一种淄博人的态度&#xff0c;一种对生活的热爱和对客人的真诚。 我想更重要的一点&#xff0c;淄博烧…

使用NineData定制企业级数据库规范

1. 为什么需要数据库规范&#xff1f; 在企业级应用中&#xff0c;数据库是非常重要的一部分&#xff0c;它们存储着公司的核心数据&#xff0c;包括客户信息、订单、产品信息等等。如果这些数据没有得到妥善的管理&#xff0c;那么就会导致数据不一致、数据丢失、数据泄露等问…

涨知识!细数银行卡三要素 API 的 N 种验证方法

引言 银行卡三要素验证 API 是一种基于姓名、身份证号码和银行卡号等三种信息的验证服务&#xff0c;主要用于绑定银行卡时校验银行卡是否为该身份信息所有、手机号是否为银行卡绑定手机号。 银行卡三要素 API 的验证方法 银行卡三要素 API 的验证原理是通过与银行或银联网络…

k8s二进制搭建|ETCD + Flannel | 单节点部署 | 多节点的部署|dashbord的部署

k8s二进制搭建|ETCD Flannel | 单节点部署 | 多节点的部署|dashbord的部署 二进制搭建 Kubernetes v1.201 初始化环境2 部署 docker引擎3 在mster 192.168.10.10上操作4 在 node01 192.168.10.20节点上操作5 在 node02 192.168.10.30节点上操作6 检查etcd群集状态7 部署 Maste…

SpringBoot——入门程序的简单介绍

简单介绍&#xff1a; 在之前我们创建了一个基础的SpringBoot的程序&#xff0c;可以看到&#xff0c;我们只是启动了一个Java程序&#xff0c;但是它启动了一个Tomcat的服务器。其实在这里面他还启动了很多的服务&#xff0c;只不过这些服务我们都没有用到&#xff0c;我们就…

基于氢储能的热电联供型微电网优化调度方法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【Slack+Claude保姆级安装教程】

&#x1f680; AI破局先行者 &#x1f680; &#x1f332; AI工具、AI绘图、AI专栏 &#x1f340; &#x1f332; 如果你想学到最前沿、最火爆的技术&#xff0c;赶快加入吧✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;CSDN-Java领域优质创作者&#x1f3c6;&am…

探究问答系统的实现原理及其应用

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

clickhouse的嵌套数据结构Tuple、Array与Nested类型介绍和使用示例

文章目录 Tuple类型Array类型Nested类型使用示例单独使用Tuple数组嵌套 Array(Tuple)Nested类型 生产使用&#xff1a;分组查询 Tuple类型 Tuple是ClickHouse数据库中的一种数据类型&#xff0c;它允许在一个字段中存储由不同数据类型组成的元组(tuple)。元组可以包含任意数量…

RFID技术在智能制造领域的发展

RFID技术在智能制造领域的发展 RFID技术是构建智能制造的基础&#xff0c;自RFID技术普及以来&#xff0c;工业产线、零售、物流、交通、医疗、制造等领域&#xff0c;都能看到到RFID应用的身影。就智能制造领域来说&#xff0c;通过RFID技术可以帮助制造企业开展各项市场需求…

shell函数数组

shell函数数组 数组的表达方式 &#xff08;30 20 10 60 50 40&#xff09; #数组0 1 2 3 4 5 #下标下标从0开始&#xff0c;中间可以断开 一&#xff1a; 数组的定义方法 方法一 数组名&#xff08;value0 value1 value2 ...&#xff09;方法二 数组名&#xff08…

网络路径下倾斜模型生产流程-模型s3c化

网络路径下倾斜模型生产流程-模型s3c化 将osgb模型处理文件拷贝到osgb模型文件夹下 在osgb模型文件夹下&#xff0c;新建与工程同名文件夹&#xff0c;然后将原文件夹下所有文件拷贝到YNPE27文件夹下&#xff0c; E:\YNPE27\CC\YNPE27\Productions\Production_2\YNPE27 打开o…

Python3,5行代码,Chatxxx能对PDF文件进行旋转、提取、合并等一系列操作,看了这篇,80岁老奶奶走路都不扶墙了。

ChatPDF的妙用 1、引言2、代码实战2.1 原理2.2 安装2.2 示例2.2.1 创建PDF文件2.2.2 旋转PDF文件2.2.3 拆分PDF文件2.2.4 合并PDF文件2.2.5 提取PDF文件内容 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c;最近干啥了&#xff1f; 小鱼&#xff1a;最近&#xff1f; 你指…

基于MATLAB的无人机遥感数据预处理与农林植被性状估算

在新一轮互联网信息技术大发展的现今&#xff0c;无人机、大数据、人工智能、物联网等新兴技术在各行各业都处于大爆发的前夜。为了将人工智能方法引入农业生产领域。首先在种植、养护等生产作业环节&#xff0c;逐步摆脱人力依赖&#xff1b;在施肥灌溉环节构建智慧节能系统&a…