常见的排序算法有冒泡排序,选择排序,堆排序,快速排序这几种,但十三写博客的目的是为了提高自己的编程解题能力,故在这里介绍如何能快速解决那些涉及到排序的编程问题,首先针对这些问题C++ STL库中已经有了sort函数可以供我们直接调用。

sort()函数

​ 使用sort()函数必须需要加上头文件#include和using namespace std; 其使用的格式如下:

sort(首元素地址, 尾元素地址的下一个地址, cmp)

​ 其中上面第三个元素cmp为非必填元素,cmp为比较函数,其设置目的为了按照程序设计者自己的思路排序(并不是按照从小到大的默认顺序排)于博主而言,cmp在sort()函数中有两个直接的作用,一是很轻松就可以做到从大到小的排列顺序,二是可以直接排序结构体中成员某些特性(PAT经常考察对结构体变量进行排序),其书写的大致逻辑如下:

bool cmp(int a,int b){return a > b;
}
bool cmp(node a,node b){return a.x > b.x;
}

​ 同样STL标准容器中只有vector,string,deque可以使用sort(),而set,map这种本就有序的容器,不允许使用sort排序。

经典习题

PAT B1015/A1062

题目链接

原题链接

题目描述

先输入考生数目,两种成绩的及格分与优秀分,再输入一批考生的id,德分和才分,再依据输入考生的德才分进行分类排序,依据如下:

  • 两门课中一门未达到及格线的考生划到第五类
  • 两门分数均超过优秀分的为第一类考生,第一类考生内部再由德才总分进行排序
  • 德分超过优秀而才分未达线者华为第二类考生,其内部亦按照德才总分排序
  • 德才均小于优秀分划为第三类考生,其内部亦按照德才总分排序
  • 其余为第四类

n个考生的排序规则:

  • 先按照类别从小到大分类
  • 类别相同,按照总分从大到小排序
  • 相同类别,相同总分,优先输出德分高的考生
  • 相同类别,相同总分,相等德分,有限输出准考证号小的

思路

使用sort()排序,cmp函数规则可以按照考生排序规则来写:

bool cmp(student a,student b){if(a.flag != b.flag) return a.flag < b.flag;else if(a.sum != b.sum) return a.sum > b.sum;else if(a.virtue != b.virtue) return a.virtue > b.virtue;else return strcmp(a.id, b.id) < 0;
}

代码

#include <iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct student{char id[10];int virtue;int talent;int sum;int flag;
};bool cmp(student a, student b){if(a.flag != b.flag) return a.flag < b.flag;else if(a.sum != b.sum) return a.sum > b.sum;else if(a.virtue != b.virtue) return a.virtue > b.virtue;else return strcmp(a.id, b.id) < 0;
}int main()
{int n,low,high;cin >> n >> low >> high;struct student stu[n];int m=n;for(int i = 0; i<n; i++){cin >> stu[i].id >> stu[i].virtue >> stu[i].talent;stu[i].sum = stu[i].virtue + stu[i].talent;if(stu[i].virtue<low||stu[i].talent<low) {stu[i].flag = 5;m--;}//分类的步骤else if(stu[i].virtue>=high&&stu[i].talent>=high) stu[i].flag = 1;else if(stu[i].virtue>=high&&stu[i].talent<high) stu[i].flag = 2;else if(stu[i].virtue>stu[i].talent) stu[i].flag = 3;else stu[i].flag = 4;}sort(stu, stu+n,cmp);//直接将n个元素按照cmp中规定好的顺序排序cout << m << endl;for(int i=0;i<m;i++){cout << stu[i].id << ' ' << stu[i].virtue << ' ' << stu[i].talent << endl;}return 0;
}

如果你那我的代码往PAT上面跑通不过hhh,肯定是超时的,不过这并不妨碍这道题作为排序算法的经典习题。

总结

为什么把本题作为排序算法的例题,因为本题排序中也有排序,读者可以点开原题链接看看原文,原文描述地云里雾里的,需要读者自己把题意抽象成一个排序中排序的模型,十三我自己开始做的时候,不愿意使用flag分类,心想最后按照要求输出不就可以了嘛,何必多此一举在结构体里面多定义一个变量占内存呢?在参考了网上大佬的代码后,立flag是为了初始分类,为了进一步使用cmp排序规则埋下伏笔的!cmp+sort()可真的是个宝贝啊,一下就解决了在我脑子里面构想的该使用哪种排序算法来解决这个问题的问题。

PAT A 1025

题目链接

原题链接

题目描述

要求最先输入考场数目n,再依次输入每个考场的考生数目k,考生的id,分数,最后输出总体考生数,并按照考生分数从高到低的次序输出每一个考生的id,总排名,考场号,所在考场排名,这里需要注意的是,分数一致的考生名次相同,下一位考生的名次则等于他所处的相对位置。

Sample Input:

2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85

Sample Output:

9
1234567890005 1 1 1
1234567890014 1 2 1
1234567890001 3 1 2
1234567890003 3 1 2
1234567890004 5 1 4
1234567890012 5 2 2
1234567890002 7 1 5
1234567890013 8 2 3
1234567890011 9 2 4

思路

本题的排序方面的方法同A 1062,有两方面排序,一个是考场内排序,另外一个是全体考生排序,其排序规则可由cmp函数决定,其排名依据有以下两点:

  • 不同分数,按照分数从大到小排
  • 相同分数,按照id从小到大排
bool cmp(Student a,Student b){if(a.scores != b.scores)return a.scores > b.scores;//不同分数按照从大到小else return strcmp(a.id,b.id) < 0;//相同分数,按照id从小到大
}

坦白说,相同分数按照id从小到大排序,这句话在题目中并未提及(或者是十三太菜没看见)十三我在提交这道题时,不加这句话,结果总是部分正确,在这里吐槽一下PTA测试平台,只告知测试点过不去,却不告知哪一个测试集没过去,这让十三找bug找的很辛苦的啊!

本题不仅仅需要对考生进行排序,还需要每个考生在所在考场,所有考场的排名,这就有点像十三上高中时,考完试时时刻刻关注着自己的班级排名,年级排名,那如何由排序好的考生得出他们各自的排名呢?分数最高的肯定时第一名,后一名的分数如果与前一名相同,则他俩名次相同,否则考生的名次就是他前面的考生数+1,以下是十三对全体考生赋予名次的代码:

stu[0].fra = 1;for(int i=1;i<m;i++){if(stu[i].scores == stu[i-1].scores) stu[i].fra = stu[i-1].fra;else stu[i].fra = i+1;}

我的代码

#include <cstdio>
#include<cstring>
#include<algorithm>struct Student{char id[14];int scores;int fra,lora;//总排名与区域排名int location;
}stu[30000];
/*比较规则*/
bool cmp(Student a,Student b){if(a.scores != b.scores)return a.scores > b.scores;//不同分数按照从大到小else return strcmp(a.id,b.id) < 0;//相同分数,按照id从小到大
}using namespace std;int main()
{int n,m=0;scanf("%d",&n);/*input data*/for(int i=0;i<n;i++){int k;//第i+1考场的考生数scanf("%d",&k);for(int j=0;j<k;j++){scanf("%s%d",stu[m+j].id,&stu[m+j].scores);//这里给第i+1个考场的考生依次赋值stu[m+j].location = i+1;}sort(stu+m,stu+m+k,cmp);//对当前考场k个考生进行排序stu[m].lora = 1;for(int t=1;t<k;t++){if(stu[m+t].scores == stu[m+t-1].scores) stu[m+t].lora = stu[m+t-1].lora;else stu[m+t].lora = t+1;}m +=k;//m是用来计算已输入考场的考生数目}sort(stu,stu+m,cmp);//对全体考生进行排序stu[0].fra = 1;for(int i=1;i<m;i++){if(stu[i].scores == stu[i-1].scores) stu[i].fra = stu[i-1].fra;else stu[i].fra = i+1;}printf("%dn",m);for(int i=0;i<m;i++){printf("%s %d %d %dn",stu[i].id,stu[i].fra,stu[i].location,stu[i].lora);}return 0;
}

vector 结构体排序_指下码上横戈行——排序相关推荐

  1. 指下码上横戈行——递归浅谈

    指下码上横戈行--递归浅谈 什么是递归,十三大一下学期上C语言课的时候,老师就在课上面讲过递归的知识,然而十三当时并没有懂,迷迷糊糊地只是把递归的两个条件记住了,一个是递归需要终止条件,另一个是递归的 ...

  2. 手机QQ侧滑菜单_从源码上一步步解析效果的实现

    本文思想来自洪洋大哥,本来写的原创的,有些朋友看到标题后认为是照搬翔哥的例子,仔细看看,会有不同,不过其中的主要思想还是翔哥的,滑动方面的算法还真是有些区别的,看完了就知道不一样,而且我这人比较啰嗦, ...

  3. 算法训练 - P1101 ——有一份提货单,其数据项目有:商品名(MC)、单价(DJ)、数量(SL)。定义一个结构体prut,其成员是上面的三项数据。在主函数中定义一个prut类型的结构体数组,输入每

    问题描述 有一份提货单,其数据项目有:商品名(MC).单价(DJ).数量(SL).定义一个结构体prut,其成员是上面的三项数据.在主函数中定义一个prut类型的结构体数组,输入每个元素的值,计算并输 ...

  4. java 3 9 2 6数字排序_GitHub - JourWon/sort-algorithm: 史上最全经典排序算法总结(Java实现)...

    史上最全经典排序算法总结(Java实现) 查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中.因为其实现代码较短,应用较常见.所以在面试中经常会问到排序算法及其相关的问题.但万变不离其宗, ...

  5. 如何把class里的vector结构体memcpy出来_面试官:请说出线程安全的 ArrayList 有哪些,除了Vector...

    以下环境是 JDK 1.8 ArrayList 的初始容量 面试官:你看过 ArrayList 的源码? Python 小星:看过 面试官:那你说下ArrayList 的初始容量是多少? Python ...

  6. vector 结构体类型 使用 排序

    如果要在Vector容器中存放结构体类型的变量,经常见到两种存放方式. 方式一:放入这个结构体类型变量的副本. 方式二:放入指向这个结构体类型变量的指针. 假设结构体类型变量是这样的, typedef ...

  7. c++ 结构体初始化_【干货】c语言基础语法——结构体

    1.关于C语言结构体的引入 学习环境搭建1_Linux C语言_嵌入式开发工程师-创客学院​www.makeru.com.cn 在实际问题中有时候我们需要几种数据类型一起来修饰某个变量. 例如一个学生 ...

  8. new 一个结构体数组_每天一个IDA小技巧(四):结构体识别

    之前提到IDA可以将一长串的数组数据声明变成一行数组声明,简化反汇编代码,对于结构体,IDA也同样支持通过各种设置工具来改善结构体代码的可读性. 这篇文章的目标是将[edx+10h]之类的结构体元素访 ...

  9. go 修改结构体方法_「GCTT 出品」Go 系列教程——26. 结构体取代类

    Go语言中文网,致力于每日分享编码.开源等知识,欢迎关注我,会有意想不到的收获! Go 支持面向对象吗? Go 并不是完全面向对象的编程语言.Go 官网的 FAQ 回答了 Go 是否是面向对象语言,摘 ...

最新文章

  1. 项目: 打字母游戏【c++/c】
  2. 命名规范(1)大小写约定
  3. python实现简易聊天需要登录博客园zip下载_Python基于Socket实现简易多人聊天室的示例代码...
  4. VMware Esxi-5.1 简介与安装
  5. sql server期中综合练习
  6. PCB画板与硬件调试+AD快捷键小技巧
  7. 云计算开发一般负责什么工作呢?云计算是做什么的?
  8. 荐书 | 9本心理治疗书籍推荐
  9. [UML]建模是什么?为什么要建模?
  10. 屏幕小于6英寸的手机_6英寸是多大?6英寸是多少厘米?
  11. 广东省电子商务认证有限公司
  12. 多媒体-windows自带录音机录音中时间限制的解决方案
  13. 印章与印鉴的区别_篆刻与印章有区别
  14. MD5加密解密算法 MD5Utils
  15. 小程序获取oppenid时返回40125或者40029
  16. 238 除自身以外数组的乘积(前后缀分解)
  17. Git Please tell me who you are
  18. 化危为机,“戴”你走近“小企业”数字化生存
  19. uniapp开发环境搭建
  20. C语言版CRC-16系列校验算法

热门文章

  1. 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 JobMasger启动 YarnJobClusterEntrypoint
  2. 【ElasticSearch】Es 源码之 DiskThresholdMonitor 源码解读
  3. 【IDEA】Cause: invalid type code: 8D
  4. 【Java】ThreadLocal SimpleDateFormat 静态代码块 空指针异常
  5. 95-235-040-源码-task-Flink 对用户代码异常处理
  6. Spring Boot 集成 Quartz
  7. 【Calcite】SQL 形式化语言——关系代数
  8. Git的使用教程(三)
  9. 可能是全网最全的 Java 日志框架适配、冲突解决方案
  10. '=='和equals区别以及jvm内存分配