STL,Sort自定义排序

文章详细介绍了C++中map、priority_queue和set的数据结构及其默认排序方式,以及如何通过自定义排序函数、排序类、结构体和lambda表达式进行排序。同时,文章提到了sort函数的自定义排序方法,包括结构体内排序、排序函数、排序函数指针和排序类的使用。
摘要由CSDN通过智能技术生成

目录

一,map

默认排序

标准库排序

示例

自定义排序

        1.排序类

        2.结构体内排序

        3.sort排序

二,priority_queue 

默认排序

标准库排序

自定义排序

        1.排序类

        3.结构体外排序

        4. lambda表达式

         5.函数指针

 三,set

默认排序

自定义排序

四,sort

        自定义排序

        1.结构体内排序

        2.排序函数

        3.排序函数指针

        4.排序类

        5.排序结构体

学习实时练习

输入格式:

输出格式:

输入样例 1:

输出样例 1:


一,map

默认排序

map中存储的是key-value键值对,默认按照key值从小到大顺序(升序)排序。即map只能按照key排序

标准库排序

std标准库中带有less<>greater<>

map<int,string,less<int>> mp;

示例

#include<iostream>
#include<map>
using namespace std;

map<int,string,greater<int> > mp;

int main()
{
	mp[1]="a";
	mp[3]="b";
	mp[0]="c";
	for(map<int,string,greater<int> >::iterator it=mp.begin();it!=mp.end();it++)
	{
		cout<<(*it).first<<" "<<(*it).second<<endl;
	}
}
 
输出:
3 b
1 a
0 c

自定义排序

        1.排序类

class cmp
{
	public:
	bool operator()(int a,int b)
	{
		return a>b;//注意return a>b是从大到小,return b>a 是从小到大
	}
};
map<int,string,cmp > mp;

        2.结构体内排序

struct node
{
	int a;
	int b;
	bool operator<( node const &n1)  const
	{
		return a > n1.a;
	}
}nod;
map<node, string > mp;

示例

#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
struct node
{
	int a;
	int b;
	bool operator<( node const &n1)  const  //注意一定要写这两个const,才能匹配函数模板构成重载
	{
		return a > n1.a;
	}
}nod;
map<node, string > mp;

int main()
{
	nod = {1,5},mp[nod] = "a";
	nod = {4,2},mp[nod] = "b";
	nod = {3,4},mp[nod] = "c";
	for (map<node, string>::iterator it = mp.begin(); it != mp.end(); it++)
	{
		cout << (*it).first.a<<" "<<(*it).first.b << " " << (*it).second << endl;
	}
}
输出:
4 2 b
3 4 c
1 5 a

        3.sort排序

map没有随机迭代器,不能使用sort函数。

二,priority_queue 

默认排序

默认升序,值按从小到大排序

标准库排序

less<> 升序    greater<> 降序

priority_queue<int,vector<int>,greater<int>> pq;

自定义排序

        1.排序类

class cmpclass
{
public:
	bool operator()(int a, int b)
	{
		return a < b;
	}
};
priority_queue<int, vector<int>, cmpclass> pq;

示例

#include<iostream>
#include<map>
#include<algorithm>
#include<queue>
using namespace std;
class cmpclass
{
public:
	bool operator()(int a, int b)
	{
		return a < b;
	}
};
priority_queue<int, vector<int>, cmpclass> pq;
int main()
{
	pq.push(1), pq.push(7), pq.push(5), pq.push(5);
	while (!pq.empty())
	{
		cout << pq.top()<<" ";
		pq.pop();
	}
}
输出(注意这是return a<b的输出,对比一下map,看区别):
7 5 5 1

        2.结构体内排序

struct node
{
	int a;
	int b;
	node() { a = 0, b = 0; }
	node(int _a, int _b) :a(_a), b(_b) {}
	bool operator<(node const& n1) const
	{
		if (a == n1.a) {
			return b >n1.b;
		}
		return a > n1.a;
	}
}nod[5];
priority_queue<node> pq;

示例

#include<iostream>
#include<map>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
	int a;
	int b;
	node() { a = 0, b = 0; }
	node(int _a, int _b) :a(_a), b(_b) {}
	bool operator<(node const& n1) const
	{
		if (a == n1.a) {
			return b >n1.b;
		}
		return a > n1.a;
	}
}nod[5];
priority_queue<node> pq;
int main()
{
	nod[1] = { 1,5 }; nod[2] = { 4,2 }; nod[3] = { 3,4 }; nod[4] = { 3,0 };
	for (int i = 1; i <= 4; i++) pq.push(nod[i]);
	while (!pq.empty())
	{
		cout << pq.top().a<<" "<<pq.top().b << endl;
		pq.pop();
	}
}

输出:
1 5
3 0
3 4
4 2

        3.结构体外排序

struct cmps {
	bool operator ()(node n1, node n2) {
		if (n1.a == n2.a) {
			return n1.b > n2.b;
		}
		return n1.a > n2.a;
	}
};

示例

#include<iostream>
#include<map>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
	int a;
	int b;
	node() { a = 0, b = 0; }
	node(int _a, int _b) :a(_a), b(_b) {}
}nod[5];
struct cmps {
	bool operator ()(node n1, node n2) {
		if (n1.a == n2.a) {
			return n1.b > n2.b;
		}
		return n1.a > n2.a;
	}
};
priority_queue<node,vector<node>,cmps> pq;
int main()
{
	nod[1] = { 1,5 }; nod[2] = { 4,2 }; nod[3] = { 3,4 }; nod[4] = { 3,0 };
	for (int i = 1; i <= 4; i++) pq.push(nod[i]);
	while (!pq.empty())
	{
		cout << pq.top().a<<" "<<pq.top().b << endl;
		pq.pop();
	}
}

        4. lambda表达式

c++中lamdbda表达式相关的知识也很多,这里不讨论lambda表达式中详细的细节问题,如有需要可以参考C++ lambda表达式
使用lambda表达式对priority_queue自定义排序的代码如下:

struct Node {
    int size;
    int price;
};

auto cmp = [](const Node &a, const Node &b) { return a.size == b.size ? a.price > b.price : a.size < b.size; };
priority_queue<Node, vector<Node>, decltype(cmp)> priorityQueue(cmp);

 由于priority_queue中的Compare模板已经确定,是一个两个参数输入,返回bool值的判断式,因此使用:

priority_queue<Node, vector<Node>, function<bool(const Node&, const Node&)>> priorityQueue(cmp);

         5.函数指针


使用函数指针与3. 使用lambda表达式类似,都是在priority_queue<.,.,Cmp>中定义Compare的类型同时在priorityQueue(cmp)的中输入具体的对象作为参数,不过 这里使用的是函数和函数的指针(地址)而不是lambda表达式对象。
具体代码如下:

bool cmpFun(const Node &a, const Node &b) {
    return a.size == b.size ? a.price > b.price : a.size < b.size;
}
bool (*p)(const Node &, const Node &) = cmpFun;
priority_queue<Node, vector<Node>, decltype(*p)> priorityQueue(*p);

类似的,decltype()也可以使用function<bool(const Node&, const Node&)>代替。

 三,set

默认排序

按元素从小到大排序(升序)

自定义排序

与前述类似

struct node
{
	int a;
	int b;
	node() { a = 0, b = 0; }
	node(int _a, int _b) :a(_a), b(_b) {}
}nod[5];

struct cmps {
	bool operator ()(const node  &n1, node n2) const{
		if (n1.a == n2.a) {
			return n1.b > n2.b;
		}
		return n1.a > n2.a;
	}
};
set<node, cmps> st;

四,sort

        自定义排序

        1.结构体内排序

struct node
{
	int a;
	int b;
	bool operator<( node const &n1)  const
	{
		return a > n1.a;
	}
}nod[10];
sort(nod,nod+10);

        2.排序函数

 bool cmpf(struct node &n1,struct node &n2) //注意加上struct
{
	if (n1.a == n1.a) return n1.b > n1.b;
	else return n1.a > n1.b;
}

        3.排序函数指针

 bool cmpf(struct node &n1,struct node &n2) 
{
	if (n1.a == n1.a) return n1.b > n1.b;
	else return n1.a > n1.b;
}
 bool (*cf)(struct node&, struct node&) = cmpf;
sort(nod + 1, nod + 5,cf );

示例:

#include<iostream>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#include<functional>
using namespace std;

struct node
{
	int a;
	int b;
	node() { a = 0, b = 0; }
	node(int _a, int _b) :a(_a), b(_b) {}
}nod[5];
 bool cmpf(struct node &n1,struct node &n2) 
{
	if (n1.a == n1.a) return n1.b > n1.b;
	else return n1.a > n1.b;
}
 bool (*cf)(struct node&, struct node&) = cmpf;
int main()
{
	nod[1] = { 1,5 }; nod[2] = { 4,2 }; nod[3] = { 3,4 }; nod[4] = { 3,0 };
	sort(nod + 1, nod + 5,cf );
	for (int i = 1; i <= 4; i++)
	{
		cout << nod[i].a << " " << nod[i].b << endl;
	}
	

}

        4.排序类

class cmpclass
{
public:
	bool operator()(struct node& n1, struct node& n2)
	{
		if (n1.a == n1.a) return n1.b > n1.b;
		else return n1.a > n1.b;
	}
}cs;
sort(nod + 1, nod + 5,cs );//不能填类型名,要实例化一个类cs

        5.排序结构体

struct cmps {
	bool operator ()(struct node& n1,struct node n2) const {
		if (n1.a == n2.a) {
			return n1.b > n2.b;
		}
		return n1.a > n2.a;
	}
}cps;//同类一样需要实例化后使用
sort(nod + 1, nod + 5,cps );

学习实时练习

题目详情 - 7-3 账户安全预警 (pintia.cn)

拼题 A 系统为提高用户账户的安全性,打算开发一个自动安全预警的功能。对每个账户的每次登录,系统会记录其登录的 IP 地址。每隔一段时间,系统将统计每个账户从多少不同的 IP 地址分别登录了多少次。如果某个账户的登录 IP 超过了 TIP​ 种,并且登录过于频繁,超过了 Tlogin​ 次,则会自动向管理员发出警报。

下面就请你实现这个预警功能。

输入格式:

输入首先在第一行中给出三个正整数:N(≤104)为登录记录的条数;TIP​ 和
Tlogin​,定义如题面中所描述,均不超过 100。

随后 N 行,每行格式为:

账户邮箱 IP地址

其中 账户邮箱 为长度不超过 40 的、不包含空格的非空字符串;IP地址 为形如 xxx.xxx.xxx.xxx 的合法 IP 地址。

输出格式:

按照登录所用不同 IP 的数量的非递增顺序,输出每个预警账户的信息。格式为:

账户邮箱
IP1 登录次数
IP2 登录次数
……

其中 IP 按登录次数的非递增顺序输出,如有并列,则按 IP 的递增字典序输出。此外,对所用不同 IP 的数量并列的用户,按其账户邮箱的递增字典序输出。

另一方面,即使没有账户达到预警线,也输出登录所用不同 IP 的数量最多的一批账户的信息。

输入样例 1:

24 3 4
daohaole@qq.com 218.109.231.189
1jiadelaolao@163.com 112.192.203.187
chenyuelaolao@zju.edu.cn 112.18.235.143
jiadelaolao@163.com 112.192.203.187
chenyuelaolao@zju.edu.cn 113.18.235.143
jiadelaolao@163.com 111.192.203.187
daohaole@qq.com 218.109.231.189
chenyuelaolao@zju.edu.cn 111.18.235.143
1jiadelaolao@163.com 115.192.203.187
daohaole@qq.com 113.189.58.141
1jiadelaolao@163.com 111.192.203.187
daohaole@qq.com 112.18.58.145
1jiadelaolao@163.com 114.192.203.187
chenyuelaolao@zju.edu.cn 112.18.235.143
daohaole@qq.com 123.89.158.214
chenyuelaolao@zju.edu.cn 112.18.235.143
youdaohaole@qq.com 218.109.231.189
jiadelaolao@163.com 113.192.203.187
youdaohaole@qq.com 218.109.231.189
jiadelaolao@163.com 114.192.203.187
youdaohaole@qq.com 113.189.58.141
youdaohaole@qq.com 123.89.158.214
1jiadelaolao@163.com 113.192.203.187
youdaohaole@qq.com 112.18.58.145

输出样例 1:

1jiadelaolao@163.com
111.192.203.187 1
112.192.203.187 1
113.192.203.187 1
114.192.203.187 1
115.192.203.187 1
daohaole@qq.com
218.109.231.189 2
112.18.58.145 1
113.189.58.141 1
123.89.158.214 1
youdaohaole@qq.com
218.109.231.189 2
112.18.58.145 1
113.189.58.141 1
123.89.158.214 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linalw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值