STL函数库的应用第二弹——快排sort函数与结构体关键字排序
时隔20多天,本蒟蒻终于记起了他的博客园密码!!!
废话不多说,今天主题:STL快排函数sort()与结构体关键字排序
Part 1:引入和导语
首先,我们需要知道,algorithm库里有一些奇怪的函数。
这些函数可以替代一些代码,使你的程序更加简洁好懂,还可以偷懒。
比如在进行DP时的状态转移时可以用的max()和min()可以快速比较两个数的大小,
又或者是abs(),看似没什么用的绝对值函数,
亦或是lower_bound(),upper_bound()拯救二分渣(比如我)的二分查找函数。
……
等等等等,只有你想不到,没有STL库的函数做不到。
我相信有很多刚开始学排序的同学被一些简单的排序题整的死去活来。明明很简单,代码却难的要死,又臭又长,根本就不想打那么复杂的代码!
而且复杂度不够优秀,更dio更优秀的归并(二分法排序)又不会写,怎么办?
Part 2:简单介绍快速排序——sort()函数
今天主要讲sort()快速排序函数,可以上述问题。
它的复杂度O(nlogn)。
这个复杂度就很优秀,比一般的冒泡,选择,插入排序都要优秀的多。
另外,sort()并不只是单纯的快速排序,他的复杂度不会像手写快速排序那样退化,稳定在O(nlogn)
对于桶,只要数据过大桶就不行了,但是sort可以轻松应对(滑稽)
另外,顺带一提,sort()默认从小到大排序,但是聪明的程序猿们不会让自己的函数这么鸡肋,所以赋予了它更强大的功能……那都是后话,一会我会专门提到。
现在请大家看程序,程序同样简洁优秀。
上基本模板代码,由于我直接sort()快速排序,所以是默认从小到大排。
#include<algorithm>
#include<cstdio>
using namespace std;
int a[];//定义您要排序的数组
int main()
{
for(int i=;i<;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+);//对它进行sort()排序,格式sort(排序数组名字+n,排序数组名字+m,???)
//这里的a是排序对象,+n和+m是指从第n项到第m-1项进行排序。???是重载函数位,一会提到。
for(int i=;i<;i++)
{
printf("%d ",a[i]);//再输出
}
return ;
}
这样就可以方便的对您的数组进行从小到大排序了,唯一要注意的是开STL库<algorithm>
很简洁对吧?但是同样,也很鸡肋,如果我想从大到小排怎么办?
教您一招!
for(int i=;i>=;i--)
{
printf("%d ",a[i]);
}
没错您可以倒着输出!!!(逃)
咳咳!说正经的,到底如何实现从大到小排序呢?
请出我们今天的大部头——cmd重载函数!
Part 3:重载您的快排函数!
吼吼吼!妈妈再也不用担心我的代码又臭又长了!但是还有一个问题没有解决——对于强迫症患者,怎么让它从大到小排序呢?(我就想从第一个元素开始循环我不管!!!)
cmd函数可以满足您的需求(我叫它cmd,dalao们可以取别的高端大气的名字QAQ)
具体如何操作?请康康我的代码。
#include<algorithm>
#include<cstdio>
using namespace std;
int a[];//定义您要排序的数组
bool cmd(int x,int y)//定义一个高端的重载函数名字,后面是两个变量 。注意是bool类型!
{
return x>y;//返回x>y,意思是当输入两个元素的时候,大的在前。(这里x>y和x>=y没有本质区别)
//反之,如果是<号的话,就是小的在前,但是那样就没意义了。
}
int main()
{
for(int i=;i<;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+,cmd);//对它进行sort()排序,格式sort(排序数组名字+n,排序数组名字+m,重载函数名字)
//这里的a是排序对象,+n和+m是指从第n项到第m-1项按重载规则进行排序。
for(int i=;i<;i++)
{
printf("%d ",a[i]);//再输出
}
return ;
}
和第一次给出的代码,只是多了一个cmd函数。
这样我们可以实现从大到小排序了。
其实不仅是从大到小排序,我们还可以干更nb的事情——关键字快速排序。来,同志们看下一part。(吸引读者阅读兴趣)
Part 4:关键字快速排序
有很多优秀(caodan)的题通常是这样的:
给出一堆人的成绩,优先按总分由高到低排序,总分一样按数学成绩由高到低排序(看不起语文英语的魂淡!!!),数学成绩一样再按输入顺序从先到后排序。
dalao们应该一眼就看出这是个结构体的题,只要开结构体就可以轻松AC,但是我们探讨的不是结构体,而是,关键字排序。
如果您使用手写冒泡等排序方法,程序必然非常优秀(caodan)。
刚才那个题是我自己瞎编的一个“经典”关键字排序,用冒泡的程序如下(我自己写了一遍,真是给自己挖坑)。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int chi,mat,eng;
struct STU{
string st;
int tot;
int math;
int num;
}QAQ[];
int main()
{
for(int i=;i<;i++)
{
cin>>QAQ[i].st;
scanf("%d%d%d",&chi,&mat,&eng);
QAQ[i].tot=chi+mat+eng;
QAQ[i].math=mat;
QAQ[i].num=i;
}
for(int i=;i>=;i--)
{
for(int j=;j<i;j++)
{
if(QAQ[j].tot<QAQ[j+].tot)
{
swap(QAQ[j],QAQ[j+]);//总分大的交换总分小的
}
if(QAQ[j].tot==QAQ[j+].tot)//总分一样看数学
{
if(QAQ[j].math<QAQ[j+].math)
{
swap(QAQ[j],QAQ[j+]);//数学大的交换数学小的
}
if(QAQ[j].math==QAQ[j+].math)//数学一样看输入顺序
{
if(QAQ[j].num>QAQ[j+].num)//输入顺序小的交换输入顺序大的
{
swap(QAQ[j],QAQ[j+]);
}
}
}
}
}
for(int i=;i<;i++)
{
cout<<QAQ[i].st<<endl;//输出名字
}
return ;
//欢迎dalao们造数据狙击我,因为没有真题,我不保证程序没有问题!!!
}
如果不用重载快排,很容易造成如上的if套娃情况。
为了拒绝套娃,让您的代码清爽一些,我们选择sort()重载排序。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int chi,mat,eng;
struct STU{
string st;
int tot;
int math;
int num;
}QAQ[];
bool cmp(STU a,STU b)
{
if(a.tot!=b.tot)
{
return a.tot>b.tot;//如果总分不一样,返回较大值
}
else
{
if(a.math!=b.math)
{
return a.math>b.math;//总分一样,数学不一样,返回数学较大值
}
else
{
return a.num<b.num;//数学也一样,返回输入顺序较小值
}
}
}
int main()
{
for(int i=;i<;i++)
{
cin>>QAQ[i].st;
scanf("%d%d%d",&chi,&mat,&eng);
QAQ[i].tot=chi+mat+eng;
QAQ[i].math=mat;
QAQ[i].num=i;
}
sort(QAQ,QAQ+,cmp);//直接排序
for(int i=;i<;i++)
{
cout<<QAQ[i].st<<" ";
}
return ;
}
您看!套娃的次数从5次减少到了2次。(好像没什么大变化啊)
但是,这只是本蒟蒻随便弄的一个题,下面上一个极其简单(caodan)的模拟/排序题。
刚学会的童鞋们建议先不要看,去洛谷找几个简单的关键字排序练习一下,毕竟这个玩意是绿题。
洛谷P1786 :帮贡排序
很显然,这题用手写关键字排序会直接死亡(不排除dalao狙击)
代码下放
//P1786
//#include<zhangtao.std>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char dd[];
struct STU{
int num;
string name;
int pos;
long long score;
int level;
}AK[];
int n;
bool cmp1(STU a,STU b)
{
if(a.score!=b.score)
{
return a.score>b.score;
}
else
{
return a.num<b.num;
}
}
bool cmp2(STU c,STU d)
{
if(c.pos!=d.pos)
{
return c.pos>d.pos;
}
else
{
if(c.level!=d.level)
{
return c.level>d.level;
}
else
{
return c.num<d.num;
}
}
}
int main()
{
cin>>n;
for(int i=;i<n;i++)
{
AK[i].num=i;
cin>>AK[i].name;
scanf("%s",dd);
if(dd[]=='B')
{
if(dd[]=='u')
{
AK[i].pos=;
}
else
{
AK[i].pos=;
}
}
if(dd[]=='F')
{
AK[i].pos=;
}
if(dd[]=='H')
{
AK[i].pos=;
}
if(dd[]=='Z')
{
AK[i].pos=;
}
if(dd[]=='T')
{
AK[i].pos=;
}
if(dd[]=='J')
{
AK[i].pos=;
}
cin>>AK[i].score>>AK[i].level;
if(AK[i].pos==)
{
AK[i].score=;
}
if(AK[i].pos==)
{
AK[i].score=;
}
}
sort(AK,AK+n,cmp1);
for(int i=;i<n;i++)
{
if(<=i&&i<=)
{
AK[i].pos=;
}
if(<=i&&i<=)
{
AK[i].pos=;
}
if(<=i&&i<=)
{
AK[i].pos=;
}
if(<=i&&i<=)
{
AK[i].pos=;
}
if(<=i)
{
AK[i].pos=;
}
}
sort(AK,AK+n,cmp2);
for(int i=;i<n;i++)
{
cout<<AK[i].name;
if(AK[i].pos==)
{
cout<<" BangZhu ";
}
if(AK[i].pos==)
{
cout<<" FuBangZhu ";
}
if(AK[i].pos==)
{
cout<<" HuFa ";
}
if(AK[i].pos==)
{
cout<<" ZhangLao ";
}
if(AK[i].pos==)
{
cout<<" TangZhu ";
}
if(AK[i].pos==)
{
cout<<" JingYing ";
}
if(AK[i].pos==)
{
cout<<" BangZhong ";
}
cout<<AK[i].level<<endl;
}
return ;
}
大家自己领会代码,主要思路就是用数字代替帮会中的位置,然后进行重载运算符,然后关键字排序即可。
今天的分享就到这里,再见dalao们!!!
STL函数库的应用第二弹——快排sort函数与结构体关键字排序的更多相关文章
- Android JNI编程(六)——C语言函数指针、Unition联合体、枚举、Typedef别名、结构体、结构体指针
版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一:函数指针 1.函数指针顾名思义就是定义一个指针变量指向一个函数,和一级指 ...
- STL函数库的应用第一弹——数据结构(队列)
队列是什么? 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作. 和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作的端称为队头 ...
- oracle函数、包、变量的定义和使用、重点”结构体和数组”
函数 实例1:输入雇员的姓名,返回该雇员的年薪 create function fun1(spName varchar2) ,); begin +nvl(comm,) into yearSal fro ...
- 快排实现仿order by多字段排序
class OrderBy(object): def __init__(self, sequence, *condition, **extra_condition): ""&quo ...
- STL set容器添加结构体并排序
#include <iostream> #include <string> #include <cstring> //strcpy #include <cst ...
- STL——sort函数简介
参考:http://blog.csdn.net/s030501408/article/details/5329477 0)与C标准库qsort的比较:http://bbs.csdn.net/topic ...
- STL 之 sort 函数使用方法
关于Sort Sort函数是C++ STL(Standard Template Library / 标准函数库) <algorithm>头文件中的一个排序函数,作用是将一系列数进行排序,因 ...
- labview从入门到出家5(进阶篇)--程序调试以及labview函数库的运用
跟了前面几章的操作流程,相信大家对labview有了一定的认识.其实只要了解了labview的编程思路,再熟悉地运用各个变量,函数以及属性,那么我们就可以打开labview的大门了.跟其他编程语言一样 ...
- F2833x 调用DSP函数库实现复数的FFT的方法
转载自:http://blog.csdn.net/aeecren/article/details/67644363:个人觉得写的很详细,值得一看 在数字信号处理中,FFT变换是经常使用到的,在DSP中 ...
随机推荐
- C++语法小记---面向对象模型(实例的内存分布)
面向对象的模型(内存分布) 对于一个对象而言,成员变量和成员函数是分开存放的 成员函数位于代码段,所有的类对象共有 成员变量为每一个对象独有,位于内存中 类对象在内存中的分布和struct完全相同 对 ...
- DC-1靶机实战和分析
前言 我们都知道,对靶机的渗透,可以宽阔自己的解题思路,练习并熟悉相关操作命令,提高自己的能力.下面我就对Vulnhub的DC-1靶机进行渗透,靶机设置了5个flag,咱们依次找到它.并通过图文形式讲 ...
- 虚拟化-SDDC软件定义数据中心
一.什么是SDDC? SDDC依赖于虚拟化和云计算技术, SDDC的目标是虚拟化数据中心的一切物理资源,通过虚拟化的技术,构建一个由虚拟资源组成的资源池,不仅是对服务器进行虚拟化,还包括存储虚拟化和网 ...
- 微信PC端多开的秘密
微信电脑端也能多开 昨天,偶然从好朋友小林(微信公众号:小林Coding)处得知,他的电脑居然可以同时上两个微信号. 手机端多开微信我知道,像华为.小米等手机系统都对此做了支持,不过在运行Window ...
- leetcode题库练习_左旋转字符串
题目:左旋转字符串 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部.请定义一个函数实现字符串左旋转操作的功能.比如,输入字符串"abcdefg"和数字2,该函数将返 ...
- 让表单input等文本框为只读不可编辑的方法-转
有时候,我们希望表单中的文本框是只读的,让用户不能修改其中的信息,如使<input type="text" name="input1" value=&qu ...
- C/C++编程笔记:C++入门知识丨函数和函数模板
本篇要学习的内容和知识结构概览 函数的参数及其传递方式 1. 函数参数传递方式 传值: 传变量值: 将实参内存中的内容拷贝一份给形参, 两者是不同的两块内存 传地址值: 将实参所对应的内存空间的地址值 ...
- 7.12 NOI模拟赛 积性函数求和 数论基础变换 莫比乌斯反演
神题! 一眼powerful number 复习了一下+推半天. 可以发现G函数只能为\(\sum_{d}[d|x]d\) 不断的推 可以发现最后需要求很多块G函数的前缀和 发现只有\(\sqrt(n ...
- luogu P4525 自适应辛普森法1
LINK:自适应辛普森法1 观察题目 这个东西 凭借我们的数学知识应该是化简不了的. 可以直接认为是一个函数 求定积分直接使用辛普森就行辣. 一种写法: double a,b,c,d; double ...
- windows:shellcode 远程线程hook/注入(一)
https://www.cnblogs.com/theseventhson/p/13199381.html 上次分享了通过APC注入方式,让目标线程运行shellcode.这么做有个前提条件:目标线程 ...