目录
一,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 );
学习实时练习
拼题 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