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