hello,各位读者大大们你们好呀
系列专栏:【C++学习与应用】
✒️✒️本篇内容:比较仿函数的代码样例,比较仿函数三种不同难度的应用示例
作者简介:计算机海洋的新进船长一枚,请多多指教( •̀֊•́ ) ̖́-
目录
一、代码样例
二、使用场景(示例)
1.简单应用
2.冒泡排序
3.priority_queue的模拟实现
比较仿函数相当于一个类对象,通常使用它的时候要求重载一个运算符 —— 括号运算符【operator()】
因为是比较仿函数,返回默认值,所以我们通常使用bool
bool operator()()
为了让仿函数使用更广泛,可将其变为模板
下面代码就实现了 x 和 y 的比较
template
class less
{
//class默认私有,所以需要加public
public:
bool operator()(const T& x, const T& y) const
{
return x < y;
}
};
template
class greater
{
public:
bool operator()(const T& x, const T& y) const
{
return x > y;
}
};
为了与库区别开来,我们通常会创造一个命名空间存放比较仿函数
#include
using namespace std;
// 仿函数/函数对象
namespace Lin
{
template
class less
{
public:
bool operator()(const T& x, const T& y) const
{
return x < y;
}
};
template
class greater
{
public:
bool operator()(const T& x, const T& y) const
{
return x > y;
}
};
}
仿函数的对象可以像函数一样使用,因此被称为仿函数
int main()
{
Lin::less lessFunc;
lessFunc(1, 2); //等价于下方的运算符重载
//lessFunc.operator()(1, 2);
}
添加一个额外的模板Compare,在函数中创建一个Compare的对象com,使代码运行时能进行推演。
转化前
template
void BubbleSort(T* a, int n)
{
...
if (a[i] < a[i - 1])
...
}
转化后
template
//void BubbleSort(T* a, int n, const Compare& com) - 没有成员变量的类只有1个字节,拷贝代价不大,因此可以不用&
void BubbleSort(T* a, int n, Compare com)
{
for (int j = 0; j < n; ++j)
{
int exchange = 0;
for (int i = 1; i < n - j; ++i)
{
//if (a[i] < a[i - 1])
if (com(a[i], a[i - 1]))
{
swap(a[i - 1], a[i]);
exchange = 1;
}
}
if (exchange == 0)
{
break;
}
}
}
测试用例
int main()
{
Lin::less lessFunc;
Lin::greater greaterFunc;
int a[] = { 2, 3, 4, 5, 6, 1, 2, 4, 9 };
//升序
//BubbleSort(a, sizeof(a) / sizeof(int), lessFunc); - lessFunc有名对象
BubbleSort(a, sizeof(a) / sizeof(int), Lin::less()); //Lin::less()匿名对象
for (auto e : a)
{
cout << e << " ";
}
cout << endl;
//降序
BubbleSort(a, sizeof(a) / sizeof(int), greaterFunc);
for (auto e : a)
{
cout << e << " ";
}
cout << endl;
return 0;
}
#include
#include
using namespace std;
namespace Lin
{
template
class less
{
public:
bool operator()(const T& x, const T& y) const
{
return x < y;
}
};
template
class greater
{
public:
bool operator()(const T& x, const T& y) const
{
return x > y;
}
};
template, class Compare = less>
class priority_queue
{
public:
priority_queue()
{}
template
priority_queue(InputIterator first, InputIterator last)
:_con(first, last)
{
//
for (int i = (_con.size() - 1 - 1) / 2; i >= 0; --i)
{
adjust_down(i);
}
}
void adjust_up(size_t child)
{
Compare com;
size_t parent = (child - 1) / 2;
while (child > 0)
{
//if (_con[parent] < con[child])
if (com(_con[parent], _con[child]))
{
swap(_con[child], _con[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
void push(const T& x)
{
_con.push_back(x);
adjust_up(_con.size() - 1);
}
void adjust_down(size_t parent)
{
Compare com;
size_t child = parent * 2 + 1;
while (child < _con.size())
{
//if (child+1 < _con.size() && _con[child] < _con[child+1])
if (child + 1 < _con.size() && com(_con[child], _con[child + 1]))
{
child++;
}
//if (_con[parent] < _con[child])
if (com(_con[parent], _con[child]))
{
swap(_con[child], _con[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void pop()
{
swap(_con[0], _con[_con.size() - 1]);
_con.pop_back();
adjust_down(0);
}
const T& top() const
{
return _con[0];
}
bool empty() const
{
return _con.empty();
}
size_t size() const
{
return _con.size();
}
private:
Container _con;
};
}
int main()
{
//Lin::priority_queue pq; // < // 大堆 - 缺省
Lin::priority_queue, greater> pq; // > // 小堆
pq.push(3);
pq.push(1);
pq.push(2);
pq.push(5);
while (!pq.empty())
{
cout << pq.top() << " ";
pq.pop();
}
cout << endl;
return 0;
}
事实上,仿函数的不仅仅只有比较仿函数一种,比较仿函数的应用场景也不仅有博主所列出来的那么少,如果大家有兴趣的话,不妨去找更多相关资料继续深入学习,这里博主仅作入门级讲解,希望能抛砖引玉。
比较仿函数的知识大概就讲到这里啦,博主后续会继续更新更多C++的相关知识,干货满满,如果觉得博主写的还不错的话,希望各位小伙伴不要吝啬手中的三连哦!你们的支持是博主坚持创作的动力!