当前位置: 首页 > article >正文

C++系列-谓词predicate

谓词predicate

  • 💢什么是谓词
    • 💢💢函数(function)谓词
    • 💢💢函数指针(function pointer)谓词
    • 💢💢函数对象(Function Object)谓词
    • 💢💢lambda表达式谓词
    • 💢💢库定义的函数对象谓词
  • 💢谓词的应用
  • 💢一元和二元谓词
    • 一元和二元谓词举例


赵师秀 宋《约客》
黄梅时节家家雨,青草池塘处处蛙。
有约不来过夜半,闲敲棋子落灯花


💢什么是谓词

  • 🥝谓词是一个可以调用的对象
  • 🥝它接收一个或一个或多个参数,并返回一个或布尔值
  • 🥝谓词通常用于算法中 ,以指定特定的条件,例如在排序算法中,可以用谓词指定排序的规则,在查找算法中,可以使用谓词来确定是否找到了满足特定条件的元素。

💢💢函数(function)谓词

  • 🍋函数的定义满足谓词的定义条件。
  • 🍋在使用时通过传递函数名实现 。

👉👉👉
先看find_if函数的定义,返回_First,是一个迭代器对象。
_Pred(_UFirst),_Pred是执行实参中传入的参数,在本类中,是一个函数名,函数名()是函数的调用。_UFirst是迭代器指向的内容。
在for循环中,循环从_First到_Last迭代器指向的每一个元素,将其作为函数的参数,执行函数操作,当出现返回true的时候,退出循环,即找到第一个满足条件的元素就退出。
vector::iterator it = find_if(vec1.begin(), vec1.end(), is_even)中的is_even要传递函数名称。是一个谓词。

_EXPORT_STD template <class _InIt, class _Pr>
_NODISCARD _CONSTEXPR20 _InIt find_if(_InIt _First, const _InIt _Last, _Pr _Pred) 
{ // find first satisfying _Pred
    _Adl_verify_range(_First, _Last);
    auto _UFirst      = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    for (; _UFirst != _ULast; ++_UFirst) {
        if (_Pred(*_UFirst)) {
            break;
        }
    }

    _Seek_wrapped(_First, _UFirst);
    return _First;
}
code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool is_even(int &val)
{
	return val % 2 == 0;
}

void test01()
{
	vector<int> vec1{1, 2, 3, 4, 5, 6};
	// find_if(_InIt _First, const _InIt _Last, _Pr _Pred) { // find first satisfying _Pred
	vector<int>::iterator it = find_if(vec1.begin(), vec1.end(), is_even);
	if(it == vec1.end())
	{
		cout << "没有找到" << endl;
	}
	else
	{
		cout << "第一个偶数是: " << *it << endl;
	}
}

int main()
{
	test01();
	system("pause");
	return 0;
}

result:
第一个偶数是: 2

💢💢函数指针(function pointer)谓词

  • 🍓使用函数指针做谓词,与上述函数做谓词基本一致,只是使用函数指针中转了一次。
  • 🍓在使用时通过传递函数指针实现 。
code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool greater_than10(int &val)
{
	return val > 10;
}

void test01()
{
	vector<int> vec1{1, 2, 13, 24, 5, 6};
	bool (*p_greater_than10)(int&); // 定义函数指针
	p_greater_than10 = greater_than10;
	vector<int>::iterator it = find_if(vec1.begin(), vec1.end(), greater_than10); // 函数指针作为谓词
	if(it == vec1.end())
	{
		cout << "没有找到" << endl;
	}
	else
	{
		cout << "第一个大于10的数是: " << *it << endl;
	}
}

int main()
{
	test01();
	system("pause");
	return 0;
}

result:
第一个大于10的数是: 13

💢💢函数对象(Function Object)谓词

  • 🍈 函数对象中重载函数的调用(), 使其可以被调用, 作为谓词。
  • 🍈 函数对象使用的本质就是对()进行运算符重载,并且返回类型为bool型,满足谓词的条件。

👉👉👉
在find_if函数中,执行 _Pred(_UFirst),_Pred是执行实参中传入的参数,在本类中,即函数对象,函数对象(_UFirst)即调用重载的()成员函数,实现了重载()函数中执行的语句。
Greater(1),创建匿名函数对象,其中的参数传入,使得在调用()时,有了明确的比较对象。

code:
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;
class Greater
{
public:
	Greater(int val) :m_base(val) {}
	bool operator()(int val)
	{
		return val > m_base;
	}
private:
	int m_base;
};

int main()
{
	vector<int>vec1 = { 0,-1,1,2,4,9,5,54,45,56 };
	// 函数对象做谓词,并且使用有参构造传入参数作为谓词判断的条件
	vector<int>::iterator iter = find_if(vec1.begin(), vec1.end(), Greater(1));
	cout << *iter << endl;
	system("pause");
	return 0;
}

result:
2

💢💢lambda表达式谓词

👉👉👉
[](int val)->bool{return val > 3;} lambda表达式作参数,这是一个匿名函数,在find_if 的_Pred(*_UFirst)中的_Pred就指向了该匿名函数。

code:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;


int main()
{
	vector<int>vec1 = { 0,-1,1,2,4,9,5,54,45,56 };
	// lambda做谓词
	vector<int>::iterator iter = find_if(vec1.begin(), vec1.end(), [](int val)->bool{return val > 3;});
	cout << *iter << endl;
	system("pause");
	return 0;
}

result:
4

库定义的函数对象(Library-Defined Function Object)谓词

💢💢库定义的函数对象谓词

  • 🍉 标准库中已经定义好一些用于特定条件判断的函数对象。
  • 🍉 比如less是用于比较两个对象的大小的函数对象谓词。

💢谓词的应用

  • 🍐谓词通常用于算法中,指定特定的条件。
  • 🍐 例如在排序算法中,可以使用谓词来定义排序的规则。在查找算法中,可以使用谓词来确定是否找到了满足特定条件的元素。

💢一元和二元谓词

  • 🥝一元谓词接受一个参数。
  • 🥝二元谓词接受两个个参数。

一元和二元谓词举例

code:
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;
class Greater
{
public:
	Greater(int val) :m_base(val) {} // 重载的(), 函数可以接受一个参数,故Greater的对象是二元谓词
	bool operator()(int val)
	{
		return val > m_base;
	}
private:
	int m_base;
};

template<class T>
class MyCompare
{
public:
	bool operator()(T val1, T val2) // 重载的(), 函数可以接受两个参数,故MyCompare的对象是二元谓词
	{
		return val1 > val2;
	}
};

void print_vector(vector<int> &vec)
{
	for (auto i_vec : vec)
	{
		cout << i_vec << " ";
	}
	cout << endl;
}

int main()
{
	vector<int>vec1 = { 0,-1,1,2,4,9,5,54,45,56 };
	cout << "排序前:" << endl;
	print_vector(vec1);
	// sort默认是升序排列,传递函数对象作为参数,改为降序排列
	sort(vec1.begin(), vec1.end(), MyCompare<int>());
	cout << "排序后:" << endl;
	print_vector(vec1);
	vector<int>::iterator iter = find_if(vec1.begin(), vec1.end(), Greater(1));
	cout << *iter << endl;

	system("pause");
	return 0;
}

result:
排序前:
0 -1 1 2 4 9 5 54 45 56
排序后:
56 54 45 9 5 4 2 1 0 -1
56

http://www.kler.cn/a/310993.html

相关文章:

  • Electron 项目启动外部可执行文件的几种方式
  • ABC334
  • MySQL数据库:SQL语言入门 【上】(学习笔记)
  • 智享AI 无人自动直播的崛起 ,引领智能互动与自动带货新潮流!
  • RHCE web解析、dns配置、firewalld配置实验
  • pgsql和mysql的自增主键差异
  • AWTK fscript 中的 CRC函数
  • 转行大模型开发:挑战与机遇,如何有效学习以实现职业转变
  • 第二证券:移动物联网迎政策助力 稀土价格有望持续回暖
  • 【C++】 —— string的使用
  • [go] 适配器模式
  • 爬虫之隧道代理:如何在爬虫中使用代理IP?
  • [Leetcode] 227.基本计算器
  • Kleopatra与MinGW64中gpg冲突
  • [Linux] 通透讲解 什么是进程
  • 嵌入式常用算法之低通滤波算法
  • libgit2编译
  • 智慧课堂学生行为数据集
  • 2024最新版 Tuxera NTFS for Mac 2023绿色版图文安装教程
  • 达梦数据库导入xml迁移到达梦数据库大文件导致中断问题解决方案记录?
  • ESP8266+httpServer+GET+POST实现网页验证密码
  • 承兑汇票识别API 银行承兑汇票识别接口 电子承兑汇票识别sdk 多进程识别
  • 鸿蒙Harmony应用开发,数据驾驶舱登录页面的实现
  • 使用python-pptx插入图片:将图片添加到幻灯片中并进行位置调整
  • 实战17-NavBar+Vip布局
  • 2024年9月python二级易错题和难题大全(附详细解析)(四)