sort自定义排序

1.SORT介绍
用于C++中,对给定区间所有元素进行排序。
使用的排序方法类似于快排的方法,时间复杂度为n * log2(n),执行效率较高
头文件#include< algorithm>
2.sort使用方法
sort函数有3个参数,sort(first, last,cmp)
其中,first是元素的起始地址,last是结束地址,cmp是排序的方式。对(first,last)区间内数据根据cmp的方式进行排序。也可以不写第三个参数,此时按默认排序,从小到大进行排序。
3.

//方案1:自定义比较函数cmp
#include<iostream>
#include<algorithm>
using namespace std;
//当b<a时,认为a小于b,所以排序的结果就是将元素按从大到小的顺序排序
bool cmp(int a,int b)
{
    return b < a;
}
int main()
{
    int a[5] = {1,5,2,4,3};
    sort(a,a + 5,cmp);
    for(int i = 0 ; i < 5 ; i++)
        cout << a[i] << endl;
}
//方案2:重载比较运算符“<”
//和方案一同理,如果认为第一个参数比第二个小就返回true,反之返回false
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);
//方案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());

例题:

/*题目1:
 读入n条学生成绩记录,包括学生姓名和总成绩,要求按成绩从高到低输出n条记录,每条记录占一行。(成绩不会重复)
 
 输入:
 第一行读入一个 n ( 0<n<=100)  接下来n行每行读入学生姓名和成绩,中间以空格隔开
 
 输出:
 n行按成绩排序的记录。
 
 样例输入
 3
 ywz 94
 lsx 85
 wjx 100
 样例输出
 wjx 100
 ywz 94
 lsx 85*/

#include<iostream>
#include<algorithm>
using namespace std;
class Student
{
public:
    string name;
    int grade;
    
};
bool operator<(const Student& s1,const Student& s2)

{
    if(s1.grade == s2.grade)
        return s1.name < s2.name;//年龄相同时,按姓名小到大排
    else return s1.grade > s2.grade;//从年龄大到小排序
}

int main()
{
    int n;
    cin >> n;
    Student s[n];
    for(int i = 0 ; i < n ; i++)
        cin >> s[i].name >> s[i].grade;
    sort(s,s + n);
    for(int i = 0; i < n ; i++)
        cout << s[i].name << " " << s[i].grade << endl;
}

/*题目2: 
读入n条学生成绩记录,包括学生姓名,总成绩,语文,数学和英语成绩,要求按总成绩从高到低输出n条记录,每条记录占一行。总成绩相同时按语文成绩从高到低输出,语文成绩相同时按数学成绩从高到低输出。(没有两个人的成绩完全一样)
 
 输入:
 第一行读入一个 n ( 0<n<=100)  接下来n行每行读入学生姓名,总成绩,语文,数学和英语成绩,中间以空格隔开
 
 输出:
 n行按要求排序好的记录。
 
 样例输入
 3
 Lsx 270 90 90 90
 Ywz 275 92 93 90
 Wjx 255 85 85 85
 样例输出
 Ywz 275 92 93 90
 Lsx 270 90 90 90
 Wjx 255 85 85 85*/


#include<iostream>
#include<algorithm>
using namespace std;
class Student
{
public:
    string name;
    int grade;
    int chinese,math,english;
    
};
bool operator<(const Student& s1,const Student& s2)

{
    if(s1.grade != s2.grade)return s1.grade > s2.grade;//如果不相等
    else//如果总成绩相同
    {
        if(s1.chinese != s2.chinese)
        return s1.chinese > s2.chinese;//总成绩相同时,按语文成绩高的排。
       
        
        if(s1.math != s2.math)
            return s1.math > s2.math;//语文也相同时,按数学成绩高的排。
        
         return s1.english > s2.english;
    }
}

int main()
{
    int n;
    cin >> n;
    Student s[n];
    for(int i = 0 ; i < n ; i++)
        cin >> s[i].name >> s[i].grade >> s[i].chinese >> s[i].math >>  s[i].english;
    sort(s,s + n);
    for(int i = 0; i < n ; i++)
        cout << s[i].name << " " << s[i].grade << " " << s[i].chinese << " " << s[i].math << " " << s[i].english << endl;
}
/*题目3:
题目描述:
 小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在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*/


#include <iostream>
#include <cstring>
#include <string>
#include <set>
#include <iterator>
#include <algorithm>
using namespace std;

int md[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

void insert(int y, int m, int d);

struct Date
{
    int year,
    month,
    day;
    
    Date(int y, int m, int d)
    {
        year = y; month = m; day = d;
    }
    
    bool operator < (Date b) const
    {
        if (year == b.year)
        {
            if (month == b.month)
                return day < b.day;
            return month < b.month;
        }
        return year < b.year;
    }
    
    bool isOK()//判断日期是否合法
    {
        if (year < 1960 || year > 2059) return false;
        if (month <= 0 || month > 12) return false;
        if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
        {
            if (month == 2)  //闰年
                return day >= 1 && day <= 29;
            return day >= 1 && day <= md[month];
        }
        else
            return day >= 1 && day <= md[month];
    }
    
    void printDate() const
    {
        printf("%d-%02d-%02d\n", year, month, day); // %02d: 不足二位则补0
    }
    
};

set<Date> ss;

void insert(int y, int m, int d)
{
    Date t(y, m, d);
    if (t.isOK()) {
        ss.insert(t);
    }
}

int main()
{
    int a, b, c;
    scanf("%d/%d/%d", &a, &b, &c);  //输入格式是 xx/xx/xx
    
        //年月日
    insert(1900+a, b, c);
    insert(2000+a, b, c);
    
        //月日年
    insert(1900+c, a, b);
    insert(2000+c, a, b);
    
        //日月年
    insert(1900+c, b, a);
    insert(2000+c, b, a);
    
    set<Date>::iterator it = ss.begin();
    
    for (; it != ss.end(); ++it)
        it->printDate();
    
    return 0;
}

  • 12
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Αиcíеиτеǎг

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值