课后作业

2024/5/15

# 第二十二课

# 1. 使用选择排序算法对一个包含学生信息的数组进行排序。每个学生的信息包括姓名(string类型)和成绩(double类型),使用选择排序对学生数组按成绩从高到低排序。如果成绩相同,则按姓名字母顺序升序排序,并计算并输出所有学生成绩的平均值和最高分与最低分之间的差值,完成后,输出学生信息

自己根据题意定义结构体,要求满足题意所有需求

// 示例输入:
5
Alice 85.5
Bob 92.0
Charlie 85.5
David 88.0
Eve 91.5
// 示例输出:
Bob 92.0
Eve 91.5
David 88.0
Alice 85.5
Charlie 85.5
平均值:88.50
最高分与最低分之差:6.50
  • 历史解析
    • 根据题目要求,使用选择排序,而你当前使用的是 sort 函数而不是选择排序算法,故错误
    • 依据示例输入输出,应保证精度为2位小数,而你的输出精度不够,故错误

# 2. 使用插入排序算法对一个包含商品信息的数组进行排序。每个商品的信息包括名称(string类型)和价格(double类型),使用插入排序对商品数组按价格从低到高排序。如果价格相同,则按名称字母顺序升序排序,并计算并输出所有商品价格的中位数,完成后,输出商品信息

自己根据题意定义结构体,要求满足题意所有需求
中位数: 如果N是奇数,则中位数为排序后第(N/2)个元素的值;如果N是偶数,则中位数为排序后第(N/2-1)和第(N/2)个元素的均值

// 示例输入:
5
Apple 3.5
Banana 2.1
Orange 2.1
Mango 4.8
Grapes 3.5
// 示例输出:
Banana 2.1
Orange 2.1
Apple 3.5
Grapes 3.5
Mango 4.8
中位数:3.50
  • 历史解析
    • 整体题解思路正确,本题主要考查插入排序算法,以及对多条件的判断处理,没有问题💯

# 3. 使用快速排序算法对一个包含员工信息的数组进行排序。每个员工的信息包括姓名(string类型)和薪资(double类型),使用快速排序对员工数组按薪资从高到低排序。如果薪资相同,则按姓名字母顺序升序排序,在排序完成后,按照以下标准将员工分成三个组

  • 高薪组:薪资在所有员工中位于前30%的员工
  • 中薪组:薪资在所有员工中位于中间40%的员工
  • 低薪组:薪资在所有员工中位于后30%的员工

最后:分别输出每个组中的员工信息,并计算并输出每个组的平均薪资

自己根据题意定义结构体,要求满足题意所有需求

// 示例输入:
6
Alice 5000
Bob 7000
Charlie 6000
David 8000
Eve 9000
Frank 4000
// 示例输出:
排序后的员工信息:
Eve 9000
David 8000
Bob 7000
Charlie 6000
Alice 5000
Frank 4000

高薪组:
Eve 9000
David 8000
平均薪资:8500.00

中薪组:
Bob 7000
Charlie 6000
平均薪资:6500.00

低薪组:
Alice 5000
Frank 4000
平均薪资:4500.00
  • 历史解析
    • 整体题解思路基本正确,本题主要考查快速排序算法,以及对多条件的判断处理,精度数处理,整体正确💯
    • 对于分组的计算,建议使用 round 函数进行分组数量计算,以确保高薪组和中薪组的数量更加精确 round 是 C++ 标准库中用于将浮点数四舍五入为最近的整数的函数。它定义在头文件 <cmath> 中。round 函数有助于在计算需要精确四舍五入结果的场景中使用,比如在分组计算时。
      点击查看 `round` 函数的使用说明
      • 函数原型
      double round(double x);
      float round(float x);
      long double round(long double x);
      

      以及:

      double round(T x); // 其中 T 是一种积分类型,可以隐式转换为 double
      
      • 使用说明 round 函数将参数 x 四舍五入到最近的整数,并返回该整数值。对于小数部分为 0.5 的情况,round 会向上舍入到最近的偶数。例如,round(2. 5) 会返回 2,而 round(3.5) 会返回 4。这种舍入方式称为 "银行家舍入"。
      • 例子
      #include <iostream>
      #include <cmath>
      using namespace std;
      int main() {
          cout << round(2.3) << endl;  // 输出 2
          cout << round(2.5) << endl;  // 输出 2
          cout << round(2.7) << endl;  // 输出 3
          cout << round(3.5) << endl;  // 输出 4
          return 0;
      }
      
      • 在分组计算中的应用 在题目要求中,需要将员工按照薪资分为高薪组、中薪组和低薪组。这些组的大小是按照员工总数的百分比计算的。如果员工总数不容易整除 10,直接用整数运算会导致某些组人数不精确。使用 round 可以更精确地计算每组的员工人数。 例如:
      int highSalaryCount = round(n * 0.3);
      int midSalaryCount = round(n * 0.4);
      int lowSalaryCount = n - highSalaryCount - midSalaryCount;
      

      假设有 7 名员工:

      • 高薪组:round(7 * 0.3) = round(2.1) = 2
      • 中薪组:round(7 * 0.4) = round(2.8) = 3
      • 低薪组:7 - 2 - 3 = 2 这种计算方式能够更好地平衡组内员工人数,从而更符合题目中的百分比要求。
      • 总结 round 函数通过四舍五入的方式将浮点数转换为最近的整数,并且能够有效处理边界值。它在各种数值计算中都十分实用,特别是在需要精确控制整数结 果的场景中,如分组计算。使用 round 可以避免简单的向下取整或向上取整带来的误差,使得结果更加合理和准确。
    • 以及涉及浮点数输出时,建议使用 fixedsetprecision 函数设置输出精度,以确保输出结果的精确性 fixedsetprecision 是 C++ 标准库中用于设置输出精度的函数。它们定义在头文件 <iomanip> 中。fixed 用于设置浮点数的输出格式为固定小数点格式,setprecision 用于设置浮点数的输出精度。
      点击查看 `fixed` 和 `setprecision` 函数的使用说明

      fixed 是 C++ 中用于控制浮点数输出格式的操纵器(manipulator)。它通常与 std::setprecision 一起使用,以确保浮点数以固定的小数位数输出。

      #include <iostream>
      #include <iomanip>
      int main() {
          double value = 123.456789;
          cout << "默认格式: " << value << endl;
          cout << fixed;
          cout << "固定格式: " << value << endl;
          cout << setprecision(2);
          cout << "固定格式,2 位小数: " << value << endl;
          cout << setprecision(4);
          cout << "固定格式,4 位小数: " << value << endl;
          return 0;
      }
      

      输出结果:

      默认格式: 123.457
      固定格式: 123.456789
      固定格式,2 位小数: 123.46
      固定格式,4 位小数: 123.4568
      

      在上面的代码中:

      1. cout << fixed; 设置了输出模式为固定小数点格式。
      2. setprecision(n) 指定了要显示的小数位数。
  • 参考答案:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <iomanip>
#include <cmath>

using namespace std;

struct Employee {
    string name;
    double salary;
};

void swap(Employee& a, Employee& b) {
    Employee temp = a;
    a = b;
    b = temp;
}

// Partition function for quicksort
int partition(vector<Employee>& employees, int low, int high) {
    Employee pivot = employees[high];
    int i = low - 1;
    for (int j = low; j < high; j++) {
        if (employees[j].salary > pivot.salary || (employees[j].salary == pivot.salary && employees[j].name < pivot.name)) {
            i++;
            swap(employees[i], employees[j]);
        }
    }
    swap(employees[i + 1], employees[high]);
    return i + 1;
}

void quicksort(vector<Employee>& employees, int low, int high) {
    if (low < high) {
        int pivot = partition(employees, low, high);
        quicksort(employees, low, pivot - 1);
        quicksort(employees, pivot + 1, high);
    }
}

int main() {
    int n;
    cin >> n;

    vector<Employee> employees(n);
    for (int i = 0; i < n; i++) {
        cin >> employees[i].name >> employees[i].salary;
    }

    quicksort(employees, 0, n - 1);

    cout << "排序后的员工信息:" << endl;
    for (const auto& employee : employees) {
        cout << employee.name << " " << employee.salary << endl;
    }

    // 使用 round 函数进行分组数量计算,以确保高薪组和中薪组的数量更加精确
    int highSalaryCount = round(n * 0.3);
    int midSalaryCount = round(n * 0.4);
    int lowSalaryCount = n - highSalaryCount - midSalaryCount;

    cout << "高薪组:" << endl;
    double highSalarySum = 0;
    for (int i = 0; i < highSalaryCount; i++) {
        cout << employees[i].name << " " << employees[i].salary << endl;
        highSalarySum += employees[i].salary;
    }
    cout << "平均薪资:" << fixed << setprecision(2) << highSalarySum / highSalaryCount << endl;

    cout << "中薪组:" << endl;
    double midSalarySum = 0;
    for (int i = highSalaryCount; i < highSalaryCount + midSalaryCount; i++) {
        cout << employees[i].name << " " << employees[i].salary << endl;
        midSalarySum += employees[i].salary;
    }
    cout << "平均薪资:" << fixed << setprecision(2) << midSalarySum / midSalaryCount << endl;

    cout << "低薪组:" << endl;
    double lowSalarySum = 0;
    for (int i = highSalaryCount + midSalaryCount; i < n; i++) {
        cout << employees[i].name << " " << employees[i].salary << endl;
        lowSalarySum += employees[i].salary;
    }
    cout << "平均薪资:" << fixed << setprecision(2) << lowSalarySum / lowSalaryCount << endl;

    return 0;
}
上次更新: 2024-10-19 10:01:51