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;

}

 

posted on 2022-07-06 23:22  Daniel_lmz  阅读(4690)  评论(0编辑  收藏  举报