课后作业
chao_smile 2024/3/3
# 第十五课
# 1. 设计一个结构体表示学生,包括学生的姓名、年龄和成绩。编写一个函数,接受一个学生结构体的数组以及数组的长度作为参数,返回成绩最高的学生的姓名和年龄
// 输入
请输入学生1的名字:Alice
请输入学生1的年龄:20
请输入学生1的分数:85.5
请输入学生2的名字:Bob
请输入学生2的年龄:22
请输入学生2的分数:90.0
请输入学生3的名字:Charlie
请输入学生3的年龄:19
请输入学生3的分数:78.3
// 输出
成绩最高的学生是 Bob 年龄 22 分数 90.0
- ✅
- 历史解析
- 题解思路正确,本题主要考查结构体的创建赋值以及使用,没有问题💯
# 2. 假设有一个结构体表示矩形(宽度和高度)。编写一个函数,接受一个矩形结构体作为参数,计算并返回该矩形的面积和周长
// 输入
请输入矩形的长:5
请输入矩形的宽:4
// 输出
矩形的面积是: 20
矩形的周长是: 18
- ✅
- 历史解析
- 题解思路正确,本题主要考查结构体的创建赋值以及使用,没有问题💯
# 3. 设计一个结构体表示员工,包括员工的姓名、工号和入职日期。然后编写一个函数,接受一个员工结构体以及当前截至日期作为参数,计算并返回该员工入职公司的年限
注意:不满入职月份不能算一年,入职年限请取整数
// 输入
请输入员工的姓名:Alice
请输入员工ID: 1001
请输入员工入职日期(年月日):2018 5 15
请输入当前日期(年月日):2024 3 3
// 输出
Alice(雇员ID: 1001)的服务年数为:5年
❌
历史解析
- 首先根据题目要求,我们需要判断的日期包含
年月日
,而你当前定义的结构体中,年只是一个单独的整型单位,即无法保证基础输入条件,故直接错误 - 之前我们讲过结构体中的成员变量可以包含结构体,如果打算使用一个成员变量来声明
年月日
的话,应当先创建一个年月日
的结构体,再用此结构体去声明 - 因缺少
月日
值,判断逻辑同步错误
- 首先根据题目要求,我们需要判断的日期包含
参考答案
#include <iostream>
using namespace std;
struct Employee {
string name;
int id;
int hireYear;
int hireMonth;
int hireDay;
};
int calculateYearsOfService(Employee employee, int currentYear, int currentMonth, int currentDay) {
int yearsOfService = currentYear - employee.hireYear;
// 如果入职月份晚于当前月份,工作年限减少1年
if (employee.hireMonth > currentMonth) {
yearsOfService--;
}
// 如果入职月份与当前月份相同但入职日期晚于当前日期,工作年限减少1年
else if (employee.hireMonth == currentMonth && employee.hireDay > currentDay) {
yearsOfService--;
}
return yearsOfService;
}
int main() {
Employee employee;
int currentYear, currentMonth, currentDay;
cout << "请输入员工的姓名:";
cin >> employee.name;
cout << "请输入员工的ID:";
cin >> employee.id;
cout << "请输入员工入职日期(年 月 日):";
cin >> employee.hireYear >> employee.hireMonth >> employee.hireDay;
cout << "请输入当前日期(年 月 日):";
cin >> currentYear >> currentMonth >> currentDay;
int yearsOfService = calculateYearsOfService(employee, currentYear, currentMonth, currentDay);
cout << employee.name << "(雇员ID:" << employee.id << ")的服务年数为:" << yearsOfService << "年" << endl;
return 0;
}
# 4. 假设有一个结构体表示三维坐标中的一个点(x、y、z)。编写一个函数,接受两个点的结构体作为参数,计算并返回这两个点之间的欧氏距离
欧氏距离(最短直线距离)是指在n
维空间中,两个点之间的距离,通常用来衡量这两个点之间的相似程度或者差异程度。在三维空间中,欧氏距离可以通过两点的坐标来计算,其计算公式如下:
如果有两个点P1(x1, y1, z1)
和P2(x2, y2, z2)
,那么它们之间的欧氏距离d
可以通过以下公式计算:
其中,(x1, y1, z1)
是第一个点的坐标,(x2, y2, z2)
是第二个点的坐标。
简而言之,欧氏距离就是两点之间的直线距离。在三维空间中,它是三维空间中点到点之间的最短距离。
// 输入
请输入第一个点的坐标(x1 y1 z1): 1.5 2.0 3.0
请输入第二点的坐标(x2 y2 z2): 4.0 5.0 6.0
// 输出
两点之间的欧氏距离:4.92443
- ✅
- 历史解析
- 函数已直接返回最短距离,没必要使用传址调用,如果后面继续涉及计算容易造成错误
- 整体题解思路正确,本题主要考查结构体的创建赋值以及使用,没有问题💯
# 5. 定义一个结构体表示日期,包括年、月和日。编写一个函数,接受两个日期结构体作为参数,计算并返回这两个日期之间相隔的天数(需要涉及润年概念)。
在考虑闰年对日期计算的影响时,主要有两个方面的规律需要考虑:
闰年的确定规律:
- 普通年份(非闰年)能被
4
整除但不能被100
整除的年份是闰年; - 能被
400
整除的年份也是闰年。
- 普通年份(非闰年)能被
闰年对月份天数的影响:
- 二月份在闰年中有
29
天,在非闰年中有28
天; - 其他月份的天数没有改变,仍然按照平年的天数来计算。
- 二月份在闰年中有
这些规律是根据格里高利历Gregorian calendar
来确定的,是现代世界中普遍使用的日历系统。
在格里高利历Gregorian calendar
中,每个月份的天数如下:
1
月:31
天2
月:28
天(闰年为29
天)3
月:31
天4
月:30
天5
月:31
天6
月:30
天7
月:31
天8
月:31
天9
月:`30 天10
月:31
天11
月:30
天12
月:31
天
注意:间隔天数应从第一个日期的 0 点算到第二个日期的 0 点,也就是相同日期的话,间隔为 0
// 输入
输入第一个日期(年月日):2024 2 1
输入第二个日期(年月日):2024 3 3
// 输出
日期之间的天数:31天
❌
历史解析
- 首先对于你的自定义函数
daysBetweenDates
不建议使用传址调用,因为并没有需要更改两个日期,如此操作会导致性能开销变大,其次容易发生计算错误 - 其次你的计算没有考虑到跨年情况下月与天的实现,当跨年后将会发生前输入月份大于后输入月份的情况,天数同理甚至会出现负值,例如尝试输入
2023 12 3``2024 1 1
,输出的确是363
- 对于跨年份计算,我们应该分批次计算。例如
2023 12 03
到2024 01 05
的间隔天数,我们应该先计算2023 12 03
到2023 12 31
也就年底的剩余天数,然后再加上2024 01 01
到2024 01 05
的天数,如此计算,然后再加上涉及跨多年度时中间完整年的值
- 首先对于你的自定义函数
参考答案
#include <iostream>
#include <cmath>
using namespace std;
struct Date {
int year;
int month;
int day;
};
bool isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
int daysInMonth(int year, int month) {
if (month == 2) {
return isLeapYear(year) ? 29 : 28;
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
return 30;
} else {
return 31;
}
}
int dayOfYear(Date date) {
int totalDays = date.day;
for (int m = 1; m < date.month; ++m) {
totalDays += daysInMonth(date.year, m);
}
return totalDays;
}
int daysBetweenDates(Date date1, Date date2) {
int daysDifference = 0;
// 如果两个日期不在同一年
if (date1.year != date2.year) {
// 计算第一个日期距离年底的剩余天数
int daysUntilEndOfYear = isLeapYear(date1.year) ? 366 - dayOfYear(date1) : 365 - dayOfYear(date1);
daysDifference += daysUntilEndOfYear;
// 计算中间年份的天数
for (int year = date1.year + 1; year < date2.year; ++year) {
daysDifference += isLeapYear(year) ? 366 : 365;
}
// 计算最后一个日期距离年初的天数
daysDifference += dayOfYear(date2);
} else {
// 如果两个日期在同一年,直接计算天数差异
daysDifference = abs(dayOfYear(date2) - dayOfYear(date1));
}
return daysDifference;
}
int main() {
Date date1, date2;
cout << "输入第一个日期 (年 月 日): ";
cin >> date1.year >> date1.month >> date1.day;
cout << "输入第二个日期 (年 月 日): ";
cin >> date2.year >> date2.month >> date2.day;
cout << "两个日期之间的天数: " << daysBetweenDates(date1, date2) << endl;
return 0;
}