写的时候不知道怎么将字符串都转换成小写了,就弄了个循环一个个将大写转换成小写。
参考了其他文章,学到了 transform() 函数,搭配 toupper 和 tolower 就可以转换成大写或者小写。
transform(begin(sname), end(sname), begin(sname), ::tolower);
第一个第二个参数是输入容器首尾地址,第三个参数是输出容器的首地址,第四个参数是操作方式。
c++ string 字符大小写的转换
虽然前面某题看了看 map 的自定义排序,但是写了写似乎不太对。所以改成把 map 的元素先输出到向量中,然后再自定义排序函数用 sort 排序。
但最后一个测试点卡了一下,根据题目黑体标明了 “整数部分” 但当时处理的方式是累加的时候直接取整 int 这样就会舍弃小数点,导致累加的结果不对。
所以改成把整数取整再放入向量中,然后再排序。
for(auto s: sch) { s.second.score = (int)s.second.s ans.push_back(s.second); } sort(begin(ans), end(ans), cmp());
顺便参考别人这个代码,可以在 push_back() 用 {} 的方式来输入一个结构体。
School{s.first, (int)s.second.score, s.second.peo}
{s.first, (int)s.second.score, s.second.peo}
经测试这两种写法都是可以的,区别只是花括号前有一个结构体的类型名。
参考代码
关于排序函数 cmp 这里参考 map 自定义里面说的,可以用 greater 或者 less 而这两都是结构体里面嵌套了重载函数。所以试了试结构体里面嵌套重载,然后把 cmp 放在 sort() 里面。
struct cmp { bool operator()(const School a, const School b) { if(a.score != b.score) return a.score > b.score; if(a.peo != b.peo) return a.peo < b.peo; return a.name < b.name; } };
关于最后同排名编号的问题,之前有一个题目处理跟这个相似 7-41 PAT排名汇总 (25 point(s)) 。
思路是记录上一个分数比较当前分数是否相同,相同继续输出上一个编号,否则更新编号。代码照着思路写一写就可以了。
又看了看 map 的自定义排序,应该认识到, map 基于红黑树结构,而结构决定了它排序方式是固定的。即便说 “自定义” 实际只是将原本的大到小变成小到大,不能到达 set 或者 sort 这种自定义的程度。
所以要写也就像这里,先放到 vector 然后再用 sort 自定义排序函数。
C++:map自定义排序
#include <bits/stdc++.h> using namespace std; struct School{ string name; double score = 0; int peo = 0; }; struct cmp { bool operator()(const School a, const School b) { if(a.score != b.score) return a.score > b.score; if(a.peo != b.peo) return a.peo < b.peo; return a.name < b.name; } }; int main() { int n; map<string, School> sch; cin >> n; while(n--){ string id, sname; int score; cin >> id >> score >> sname; // 不区分大小写 transform(begin(sname), end(sname), begin(sname), ::tolower); // 输入对应学校的数据 // 判断哪个比赛 if(id[0] == 'B') {sch[sname].score += score * 1.0 / 1.5;} if(id[0] == 'A') {sch[sname].score += score ;} if(id[0] == 'T') {sch[sname].score += score * 1.5;} sch[sname].peo++; sch[sname].name = sname; } vector<School> ans; for(auto s: sch) ans.push_back(School{s.first, (int)s.second.score, s.second.peo}); sort(begin(ans), end(ans), cmp()); // 编号 保存上一个输出的分数 int i = 1, j = 1, last = -1; cout << ans.size() << endl; for(auto a: ans){ // 如果分数不一样则更新编号 if(last != a.score) { j = i; last = a.score; } cout << j << " " << a.name << " " << (int)a.score << " " << a.peo << endl; i++; } }