课后作业
chao_smile 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
可以避免简单的向下取整或向上取整带来的误差,使得结果更加合理和准确。
- 以及涉及浮点数输出时,建议使用
fixed
和setprecision
函数设置输出精度,以确保输出结果的精确性fixed
和setprecision
是 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
在上面的代码中:
cout << fixed;
设置了输出模式为固定小数点格式。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;
}