C++中的sort自定义排序函数
C++中sort自定义排序
1.sort简介:
(1)用于C++中,对给定区间所有元素进行排序;
(2)使用的排序方法是类似于快排的方法,时间复杂度为n*log2(n),执行效率较高;
(3)头文件 #include <algorithm>。
2.sort使用方法
sort函数有三个参数
sort(first,last,cmp);
其中,first是元素的起始地址,last是结束地址,cmp是排序的方式。对[first,last)(一定要注意这里的区间是左闭又开)区间内数据根据cmp的方式进行排序。也可以不写第三个参数,此时按默认排序,从小到大进行排序。
3.自定义排序
(1)自定义比较函数cmp
比如:
bool cmp(int a,int b)
{
return b<a;
}
sort(a,a+n,cmp);
传入的参数类型和需要排序的数据类型一致,如果认为第一个参数比第二个小,也就是第一个参数需要排在第二个参数前面时返回true,反之返回 false。系统默认a<b时返回true,于是从小到大排。而上面的例子是当b小于a时,认为a小于b。所以排序的结果就是将元素按从大到小的顺序排序。
(2)重载比较运算符“<”
如:
bool operator< (const Student& s1, const Student& s2)
{
if(s1.age==s2.age)
return s1.name <s2.name;//年龄相同时,按姓名小到大排
else return s1.age > s2.age; //从年龄大到小排序
}
sort(a,a+n);
这里一定要注意一下:
参数类型如果是自定义类型,比如自己定义的结构体,类,尽管sort函数默认是从小到大排列,但是这里必须要重载比较运算符“<”!!!
和cmp函数同理,如果认为第一个参数比第二个小就返回true,反之返回 false。
(3)声明比较类
struct cmp
{
bool operator() (const Student& s1, const Student& s2)
{
if(s1.age==s2.age)
return s1.name <s2.name;
else return s1.age < s2.age;
}
};
sort(a,a+n,cmp());
还是同理,如果认为第一个参数比第二个小就返回true,反之返回 false。
(4) functional提供了一堆基于模板的比较函数对象:equal_to<Type>、not_equal_to<Type>、greater<Type>、greater_equal<Type>、less<Type>、less_equal<Type>。对于这个问题来说,greater和less就足够了,直接拿过来用:
升序:sort(begin,end,less<data-type>());
降序:sort(begin,end,greater<data-type>()。
【第八届蓝桥杯】日期问题
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。 比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。 给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
输入:
一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)
输出:
输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。
样例输入:
02/03/04
样例输出:
2002-03-04
2004-02-03
2004-03-02
思路:自定义date结构体,
对输入的三个数字按年月日月日年日月年的排序分别判断其合理性,若合理则存入数组中,最后排序去重后按要求输出。
#include <iostream>
#include <algorithm>
using namespace std;
class date
{
public:
int year;
int month;
int day;
};
date x[100];
bool operator<(const date& a, const date& b)
{
//重载<符号来比较日期的大小
if (b.year == a.year)
{
if (b.month == a.month)
{
return a.day < b.day;
}
else
{
return a.month < b.month;
}
}
else
{
return a.year < b.year;
}
}
int md[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
bool judge(date a)
{
if (a.year < 1960 || a.year>2059)
return false;
if (a.month <= 0 || a.month > 12)
return false;
if (a.year % 400 == 0 || (a.year % 100 != 0 && a.year % 4 == 0))
{
//闰年
if (a.month == 2)
{
return a.day >= 1 && a.day <= 29;
}
return a.day >= 1 && a.day <= md[a.month];
}
else
return a.day >= 1 && a.day <= md[a.month];
}
int cnt = 0;
void myscanf(int a, int b, int c)
{
//如果日期合法则插入数组中
date d;
d.year = a;
d.month = b;
d.day = c;
if (judge(d))
{
x[cnt++] = d;
}
}
int main()
{
int a, b, c;
scanf_s("%d/%d/%d", &a, &b, &c);
//年月日
myscanf(1900 + a, b, c);
myscanf(2000 + a, b, c);
//月日年
myscanf(1900 + c, a, b);
myscanf(2000 + c, a, b);
//日月年
myscanf(1900 + c, b, a);
myscanf(2000 + c, b, a);
sort(x, x + cnt);
for (int i = 0; i < cnt; ++i)
{
//去重
if (x[i].year != x[i - 1].year || x[i].month != x[i - 1].month || x[i].day != x[i - 1].day)
printf("%d-%02d-%02d\n", x[i].year, x[i].month, x[i].day);
}
system("pause");
return 0;
}