【C++刷题笔记】函数指针与仿函数:自定义排序规则
C++中的sort函数性能十分强大,有时我们需要自定义排序方式,sort的第三个参数接收一个bool类型的函数指针,用来指定排序的规则。
方法一:传函数指针的方式:
定义一个降序函数
template<typename T>
bool descend(T & a, T &b) {
return a > b; //降序排列
}
我这里有个记忆的小窍门,等号朝左边开,说明左边大,也就意味着降序排列。
测试一下:
int main()
{
vector<int> inp = { 1,241,6,24,7,8,23,67,2 };
sort(inp.begin(), inp.end(), descend<int>);
for (auto && x : inp) {
cout << x << " ";
}
cout << endl;
}
方法二:传仿函数的方式:
通过重载()运算符,定义一个升序仿函数
template<typename T>
struct ascend {
bool operator() (T & a,T & b) {
return a < b; //升序排列
}
};
测试一下,注意这里ascend<int>()
传的仍然是一个函数指针,因为ascend<int>
本质上是指定了模板类型为int的一个类,而()
就是这个类里的运算符,相当于是成员函数,因此ascend<int>()
表示ascend
类里的()
运算符(函数)。
int main()
{
vector<int> inp = { 1,241,6,24,7,8,23,67,2 };
sort(inp.begin(), inp.end(), ascend<int>());
for (auto && x : inp) {
cout << x << " ";
}
cout << endl;
}
自带的less和greater
自带的less和greater本质上就是仿函数,查看一下less
的源码就一目了然了:
template<class _Ty = void>
struct less
{ // functor for operator<
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef bool result_type;
constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator< to operands
return (_Left < _Right);
}
};
因此用在sort里要加上()
运算符。
sort(inp.begin(), inp.end(), less<int>());
priority_queue的情况
priority_queue 的 第三个参数就不是函数指针,而是仿函数了,因此上面的方法一就不能用了。
//升序队列,头部是最小的元素,即小顶堆
priority_queue <int,vector<int>,greater<int> > q;
//降序队列,头部是最大的元素,即小顶堆
priority_queue <int,vector<int>,less<int> >q;