课后作业

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可以通过以下公式计算:

15-1

其中,(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. 定义一个结构体表示日期,包括年、月和日。编写一个函数,接受两个日期结构体作为参数,计算并返回这两个日期之间相隔的天数(需要涉及润年概念)。

在考虑闰年对日期计算的影响时,主要有两个方面的规律需要考虑:

  1. 闰年的确定规律:

    • 普通年份(非闰年)能被4整除但不能被100整除的年份是闰年;
    • 能被400整除的年份也是闰年。
  2. 闰年对月份天数的影响:

    • 二月份在闰年中有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 032024 01 05的间隔天数,我们应该先计算2023 12 032023 12 31也就年底的剩余天数,然后再加上2024 01 012024 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;
}
上次更新: 2024-10-19 10:01:51