【多关键字排序专题】C++sort函数自定义排序规则,map、unordered_map按照value排序/自定义排序规则
map按value排序/自定义排序规则
不能直接排,需要把map
放入到vector中再对vector排序
方法如下
using PSI = pair<string, int>;
vector<PSI> arr;
unordered_map<string, int> mp;
for (auto &[k, v] : mp) arr.push_back({k, v});
sort(arr.begin(), arr.end(), [](PSI a, PSI b) {
return a.second < b.second;
});
例题 字符串重新排序
样例1
输入
This is an apple
输出
an is This aelpp
样例2
输入
My sister is in the house not in the yard
输出
in in eht eht My is not adry ehosu eirsst
C++代码
#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
using PSI = pair<string, int>;
string str;
vector<PSI> arr;
unordered_map<string, int> mp;
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
while (cin >> str)
{
sort(str.begin(), str.end());
mp[str]++;
}
for (auto &[k, v] : mp) arr.push_back({k, v});
sort(arr.begin(), arr.end(),
[](PSI a, PSI b)
{
if (a.second != b.second) return a.second > b.second;
if (a.first.size() != b.first.size())
return a.first.size() < b.first.size();
return a.first < b.first;
});
for (auto &[k, v] : arr)
{
if (v == 1) cout << k << ' ';
else
{
for (int i = 0; i < v; i++) cout << k << ' ';
}
}
return 0;
}
优秀学员统计
样例1
输入
11
4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2
0 1 7 10
0 1 6 10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
6 10
7 10
输出
10 0 1 7 6
说明:
员工编号范围为0~10,id为10的员工连续打卡30天,排第一, id为0,1,6,7的员工打卡都是两天, id为0,1,7的员工在第一天就打卡, 比id为6的员工早,排在前面,0,1,7按id升序排列, 所以输出[10,0,1,7,6]
样例2
输入
7
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5
输出
0 1 2 3 4
说明:
员工编号范围为0-6,id为0,1, 2, 3, 4,5的员工打卡次数相同,最早开始打卡的时间也一样,所以按id升序返回前5个id
样例3
输入
2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0 1
0 1
输出
1 0
说明:
只有两名员工参与打卡,按规则排序输出两名员工的id
C++代码
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
using PII = pair<int, int>;
const int N = 110;
int n, sum; // sum记录当月打卡的员工数量
int day[N];
struct Node
{
int id, cnt, fday;
bool operator<(const Node &t) const
{
if (cnt != t.cnt) return cnt > t.cnt;
if (fday != t.fday) return fday < t.fday;
return id < t.id;
}
} node[N];
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 0; i < n; i++) node[i].id = i;
for (int i = 0; i < 30; i++) cin >> day[i];
for (int i = 0; i < 30; i++)
{
int T = day[i];
while (T--)
{
int x;
cin >> x;
if (node[x].cnt == 0) node[x].fday = i, sum++;
node[x].cnt++;
}
}
sort(node, node + n);
if (sum >= 5) sum = 5;
for (int i = 0; i < sum; i++) cout << node[i].id << ' ';
return 0;
}
练习题
429. 奖学金
重载小于号写法
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 310;
int n;
struct Person
{
int id, sum, a, b, c;
bool operator< (const Person& t) const
{
if (sum != t.sum) return sum > t.sum;
if (a != t.a) return a > t.a;
return id < t.id;
}
}q[N];
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++ )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
q[i] = {i, a + b + c, a, b, c};
}
sort(q + 1, q + n + 1);
for(int i = 1; i <= 5; i ++ )
cout << q[i].id << ' ' << q[i].sum << endl;
return 0;
}
自定义比较函数写法
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 310;
int n;
struct Person
{
int id, sum, a, b, c;
}q[N];
bool cmp(Person &a, Person &b)
{
if (a.sum != b.sum) return a.sum > b.sum;
if (a.a != b.a) return a.a > b.a;
return a.id < b.id;
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i ++ )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
q[i] = {i, a + b + c, a, b, c};
}
sort(q + 1, q + n + 1, cmp);
for(int i = 1; i <= 5; i ++ )
cout << q[i].id << ' ' << q[i].sum << endl;
return 0;
}
字符统计及重排
从本题可以学到小写字母排在大写字母前的写法,因为小写字母ASCII码比大写字母ACSII码大,如果按字典序排的话是大写字母在小写字母前
#include <algorithm>
#include <iostream>
#include <unordered_map>
using namespace std;
const int N = 60;
int k;
unordered_map<char, int> h;
struct Node
{
char word;
int cnt;
bool operator<(const Node &t) const
{
if (cnt != t.cnt) return cnt > t.cnt;
if (islower(word) != islower(t.word))
return islower(word) > islower(t.word); // 小写字母在大写字母前
return word < t.word;
}
} node[N];
int main()
{
string s;
cin >> s;
for (auto &x : s) h[x]++;
for (auto &x : h)
{
node[k++] = {x.first, x.second};
}
sort(node, node + k);
for (int i = 0; i < k; i++)
{
printf("%c:%d;", node[i].word, node[i].cnt);
}
return 0;
}
3375. 成绩排序
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1010;
int n, type;
struct Person
{
string name;
int score;
int id;
bool operator< (const Person& t) const
{
if(score != t.score) return score < t.score;
return id < t.id; //如果分数相同,则序号小的在前
}
bool operator> (const Person& t) const
{
if(score != t.score) return score > t.score; //分数不同,分数大的在前面
return id < t.id; // 这里易写错,分数相同,序号小的在前面
}
}q[N];
int main()
{
cin >> n >> type;
for (int i = 0; i < n; i ++ )
{
cin >> q[i].name >> q[i].score;
q[i].id = i;
}
if(type == 0) sort(q, q + n, greater<Person>());
else sort(q, q + n);
for (int i = 0; i < n; i ++ )
cout << q[i].name << ' ' << q[i].score << endl;
return 0;
}
3376. 成绩排序2
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 110;
int n;
struct Person
{
int id, score;
bool operator< (const Person& t) const
{
if (score != t.score) return score < t.score;
return id < t.id;
}
}q[N];
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ ) cin >> q[i].id >> q[i].score;
sort(q, q + n);
for (int i = 0; i < n; i ++ )
cout << q[i].id << ' ' << q[i].score << endl;
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析