STL & 自定义比较器

说明:
    采用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();
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值