蓝桥杯-sort排序(下)

🎈1.算法说明

🔎我们知道,如果我们定义一个基本数据类型的话,我们是可以直接给出它的初始值的。对于结构体这样一个我们自己定义的对象来说,除非事先给出明确的规定,编译器是不知道该按照什么样的规则来进行初始化的。为了解决这个问题,C++语言的语法中,为我们提供了一种特殊的机制-那就是构造函数。构造函数是一种定义在结构体中的特殊函数,它可以被用于描述对结构体进行初始化的算法。比如说对于我们定义的Student结构体,我们可以定义一个具有两个参数的构造函数,分别为一个整型变量和一个string变量。这样,当我们定义结构体的时候,就可以直接用这样的方式,一步到位的完成结构体成员的赋值:

cin>>score_input>>name_input;
Student stu(score_input,name_input);

📝结构体构造函数的定义方法如下所示-在C++中,结构体内不仅可以定义变量成员,也可以定义函数成员。

struct Student
{
	int score;
	string name;
	Student(string n, int s)
	{
		name = n;
		score = s;
	}
};

✅在语法上,构造函数具有这样的性质:

  • 函数名与结构体名完全相同。
  • 不能定义返回值类型,不能有return语句。
  • 可以有形参,也可以没有形参,可以带有默认参数。
  • 可以重载。

在使用的时候,我们不需要手动调用构造函数。当我们创建结构体的时候,构造函数会自动被调用。

我们定义构造函数的时候,可以有参数表,也可以让参数表空着-同样,即使是一个构造函数有参数,我们也可以给它的所有参数都设置一个默认值。这样的构造函数,称为默认构造函数,如下所示:

struct Student
{
	int score;
	string name;
	Student(){}
};

❗注意,同一个结构体中,不能出现两个默认构造函数,例如下面这段代码:

struct Student
{
	int score;
	string name;
	Student(){}
	Student(string n="",int s=0){}
};

🔭可能你有这样一个疑问,我们在定义Student结构体的时候并没有定义构造函数,那么这个时候,Student结构体生成的对象又该如何进行初始化呢?事实上,如果我们定义一个结构体的时候,不声明任何构造函数,那么编译器在编译的时候,就会为我们自动生成一个默认构造函数,它具有这样的特点:

  1. 参数列表为空,不为数据成员赋初值。如果结构体内定义了成员的初始值,则使用结构体内定义的初始值。
  2. 如果没有定义结构体内的初始值,则以默认方式初始化。
  3. 基本类型的数据默认初始化的值是不确定的。

简而言之,这样的一个构造函数,它的特点就是“什么都不做”,单纯只是创建一个结构体而已-相当于这样的一个形式:

Student() {

}

需要注意的是,如果我们在结构体中已经定义了一个构造函数(可以是任意形式)的话,那么编译器就不会再为我们定义默认构造函数了-这个时候,如果我们需要使用到默认构造函数的话,不要忘记自己再定义它。
✅对于开发更加复杂的程序,我们往往要构造函数在初始化过程中做很多事情,但是对于竞赛来说,我们只需要构造函数给结构体赋初始值就行了-所以我们其实可以使用另一种更加简单的方式,初始化列表,来直接对结构体成员进行初始化:

struct Student
{
	int score;
	string name;
	Student() {}
	Student(string n, int s) :name(n), score(s) {}
};

如上所示,初始化列表的写法是,在构造函数的括号后面加上一个冒号,然后按照成员变量(参数)的格式,依次对每一个变量进行初始化,彼此之间用逗号隔开。
注意

  • 函数的参数列表绝对不能省略,像Student():name(n),score(s)这样的写法是不允许的。
  • 如果在初始化完成成员变量之后,还有别的事情要做,那就可以把代码写在大括号里,但是,就算之后什么都不做,也必须写大括号

🎈2.例题

🔭2.1例题一

🔎题目:输入三个学生的名字和四个成绩,在这里,我们想把学生以及它的成绩作为一个整体进行排序。排序的依据是:

  • 当第一个成绩高的时候,第一个成绩高的排在前面。
  • 当第一个成绩相同时,第二个成绩高的排在前面。
  • 当前两个成绩相同时,第三个成绩高的排在前面。
  • 当前三个成绩相同时,第四个成绩高的排在前面。

🔎算法

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct Student
{
	string name;
	int score[4];
};
bool cmp(Student x, Student y)
{
	if (x.score[0] != y.score[0])
		return x.score[0] > y.score[0];
	if (x.score[1] != y.score[1])
		return x.score[1] > y.score[1];
	if (x.score[2] != y.score[2])
		return x.score[2] > y.score[2];
	if (x.score[3] != y.score[3])
		return x.score[3] > y.score[3];
}
int main()
{
	Student stu[3];
	cout << "排序前:" << endl;
	for (int i = 0; i < 3; i++)
	{
		cin >> stu[i].name;
		for (int j = 0; j < 4; j++)
		{
			cin >> stu[i].score[j];
		}
	}
	sort(stu, stu + 3, cmp);
	cout << "排序后:" << endl;
	for (int i = 0; i < 3; i++)
	{
		cout << stu[i].name << ":";
		for (int j = 0; j < 4; j++)
		{
			cout << stu[i].score[j] << " ";
		}
		cout << endl;
	}
	return 0;
}

在这里插入图片描述

🔭2.2例题二

🔎题目:东东所在的班级有N名学生,期末考试进行了数学、语文、英语以及地理四门功课的测试。班主任要将这N名学生中总分前三名定为本学期的学习标兵。现给出这N名学生的姓名和各科成绩,请你编程找到总分的前三名,并依次输出他们的姓名,所给数据不存在总分相同的情况。输入格式:输入包含N+1行,第一行仅有一个正整数N(3<=N<=40),表示东东班里学生的总数,接下来的N行,每行描述一个学生的考试信息,依次为姓名、数学成绩、语文成绩、英语成绩与地理成绩,两两之间用空格隔开。注意:姓名不会同名,都用小写字母表示,成绩全为不超过200的非负整数。输出格式:输出包含三行,每行仅包括一个学生的姓名,依次为第一名到第三名的学生的姓名。
🔎算法

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct Student
{
	string name;
	int score[4];
};
bool cmp(Student x, Student y)
{
	int sumx = x.score[0] + x.score[1] + x.score[2] + x.score[3];
	int sumy = y.score[0] + y.score[1] + y.score[2] + y.score[3];
	return sumx > sumy;
}
Student stu[40];
int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> stu[i].name;
		for (int j = 0; j < 4; j++)
		{
			cin >> stu[i].score[j];
		}
	}
	sort(stu, stu + n, cmp);
	for (int i = 0; i < 3; i++)
	{
		cout << stu[i].name << endl;
	}
	return 0;
}

在这里插入图片描述

好啦,关于sort排序的知识到这里就先结束啦,后期会继续更新学习蓝桥杯的相关知识,欢迎大家持续关注、点赞和评论!❤️❤️❤️

  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一口⁵个团子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值