说明:
采用sort函数举例(sort函数能够接收 2个
形参)
用途
说明
STL中的绝大多数用于查找
、排序
的函数的前2个参数基本上都是一个范围[first, last],第3个参数一般是一个比较器仿函数
(即: 设定大小比较原则compare)
下面介绍 5种
常见的比较器定义手段:
① 自定义普通比较器函数cmp
#include<iostream>
#include<vector>
#include<functional>
#include<algorithm>
using namespace std;
// [1] 自定义比较器函数cmp,用于sort排序
bool cmp(pair<int, int>& a, pair<int, int>& b){ //用于sort函数
if (a.first != b.first)
return a.first < b.first; //升序
else
return a.second < b.second; //升序
}
int main(){
vector<pair<int, int>> vec; //vec不是自动排序的,因此没有greater函数
vec.emplace_back(1, 1);
vec.emplace_back(2, 1);
vec.emplace_back(2, 4);
vec.emplace_back(2, 1);
vec.emplace_back(3, 1);
sort(vec.begin(), vec.end(), cmp); //排序
// [2] STL自定义的仿函数 greater<type>()
sort( vec.begin(), vec.end(),greater<pair<int,int>>() );
}
② STL自带的仿函数 greater<type>()
int main(){
vector<pair<int, int>> vec; //vec不是自动排序的,因此没有greater函数
vec.emplace_back(1, 1);
vec.emplace_back(2, 1);
vec.emplace_back(2, 4);
vec.emplace_back(2, 1);
vec.emplace_back(3, 1);
// STL自定义的仿函数 greater<type>()
sort( vec.begin(), vec.end(),greater<pair<int,int>>() );
}
③ 定义全局的 operator< 函数
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
class Node{
public:
int key;
int val;
public:
Node(int h, int i) :key(h), val(i){}
};
// 定义全局的operator< ,参数是const
bool operator<(const Node& a, const Node& b){
if (a.key != b.key)
return a.key < b.key; //升序
else
return a.val < b.val; //升序
}
int main(){
vector<Node> vec;
vec.emplace_back(Node(1, 5));
vec.emplace_back(Node(1, 2));
vec.emplace_back(Node(1, 3));
vec.emplace_back(Node(1, 1));
vec.emplace_back(Node(2, 5));
vec.emplace_back(Node(2, 2));
vec.emplace_back(Node(3, 3));
vec.emplace_back(Node(3, 1));
sort(vec.begin(), vec.end());
for_each(vec.begin(), vec.end(), [](Node node){cout << node.key << " " << node.val << endl; });
system("pause");
}
④ vector 的仿函数类的对象
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
class Node{
public:
int key;
int val;
public:
Node(int h, int i) :key(h), val(i){}
};
// [仿函数类]
class CmpASC{ // 升序
public:
bool operator()(const Node& a, const Node& b){
if (a.key != b.key)
return a.key < b.key;
else
return a.val < b.val;
}
};
// [仿函数类]
class CmpDesc{ //降序
public:
bool operator()(const Node& a, const Node& b){
if (a.key != b.key)
return a.key > b.key;
else
return a.val > b.val;
}
};
int main(){
vector<Node> vec;
vec.emplace_back(Node(1, 5));
vec.emplace_back(Node(1, 2));
vec.emplace_back(Node(1, 3));
vec.emplace_back(Node(1, 1));
vec.emplace_back(Node(2, 5));
vec.emplace_back(Node(2, 2));
vec.emplace_back(Node(3, 3));
vec.emplace_back(Node(3, 1));
// sort第3参数 = 仿函数类的对象 CmpDesc()
sort(vec.begin(), vec.end(), CmpDesc());
// sort第3参数 = 仿函数类的对象 CmpASC()
sort(vec.begin(), vec.end(), CmpASC());
for_each(vec.begin(), vec.end(), [](Node node){cout << node.key << " " << node.val << endl; });
system("pause");
}
⑤ set / mutilset / map / mutilset 自动排序
说明:set / mutilset / map / mutilset 是基于红黑树结构的,当插入元素的时,元素会自动排序(排序的规则可以人为的指定),详细步骤如下(3步):
[1] 定义仿函数类,重写operator()
class CmpASC
{
bool operator()(___,___) { … …} //重写()运算符
};
[2] 创建容器对象set,通过第2参数 CmpASC
指定插入元素的排序规则
multiset<Node, CmpASC
> set;
[3] 插入元素时,会按照 CmpASC 定义的大小比较规则排序
set.emplace(___);
#include<iostream>
#include<vector>
#include<set>
using namespace std;
class Node{
public:
int key;
int val;
public:
Node(int h, int i) :key(h), val(i){}
};
//方式3:
class CmpASC{ //仿函数
public:
bool operator()(const Node& a, const Node& b){ //参数类型:const
if (a.key != b.key)
return a.key < b.key; //升序
else
return a.val < b.val; //升序
}
};
class CmpDesc{ //仿函数
public:
bool operator()(const Node& a, const Node& b){
if (a.key != b.key)
return a.key > b.key; //降序
else
return a.val > b.val; //降序
}
};
void test01(){ //升序
multiset<Node, CmpASC> set; //
set.emplace(Node(1, 5));
set.emplace(Node(1, 2));
set.emplace(Node(1, 3));
set.emplace(Node(1, 1));
set.emplace(Node(2, 5));
set.emplace(Node(2, 2));
set.emplace(Node(3, 3));
set.emplace(Node(3, 1));
}
void test02(){ //降序
multiset<Node, CmpDesc> set; //
set.emplace(Node(1, 5));
set.emplace(Node(1, 2));
set.emplace(Node(1, 3));
set.emplace(Node(1, 1));
set.emplace(Node(2, 5));
set.emplace(Node(2, 2));
set.emplace(Node(3, 3));
set.emplace(Node(3, 1));
}
int main(){
test01();
}