STL 算法
本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 73 课,共 104 课。
STL 算法是作用于由迭代器定义的范围的模板函数。它们位于 <algorithm> 和 <numeric> 头文件中,并且适用于任何提供兼容迭代器的容器。
std::sort 默认按升序排列元素:
#include <algorithm>
#include <vector>
std::vector<int> nums = {5, 2, 8, 1};
std::sort(nums.begin(), nums.end());
// nums: {1, 2, 5, 8}std::find 会搜索一个值,并返回指向第一个匹配项的迭代器;如果没有找到,则返回 end():
auto it = std::find(nums.begin(), nums.end(), 5);
if (it != nums.end()) {
std::cout << "Found at index: " << (it - nums.begin());
}std::transform 对每个元素执行操作,并将结果存储在目标范围内:
std::vector<int> doubled(nums.size());
std::transform(nums.begin(), nums.end(), doubled.begin(),
[](int x) { return x * 2; });
// doubled: {2, 4, 10, 16}std::accumulate(来自 <numeric>)会将所有元素合并为一个值:
#include <numeric>
int sum = std::accumulate(nums.begin(), nums.end(), 0);
// sum:16(1 + 2 + 5 + 8)这些算法接受迭代器范围,而不是直接接受容器,因此足够灵活,可以使用相同的代码处理部分范围或不同类型的容器。
挑战
简单让我们使用 STL 算法构建一个分数分析器,处理一组数字。你将创建一些实用函数,演示 sort、find、transform 和 accumulate 如何协同分析数据。
你将把代码分别写在两个文件中:
ScoreAnalyzer.h:定义使用 STL 算法处理整数向量的实用函数。创建一个名为
sortScores的函数,接收一个std::vector<int>&,并使用std::sort按升序排序。创建一个名为
findScore的函数,接收一个const std::vector<int>&和一个int类型的目标值。使用std::find查找目标值。如果找到,返回其索引(与 begin 的距离)。如果没有找到,返回-1。创建一个名为
applyBonus的函数,接收一个const std::vector<int>&和一个int类型的加分值。使用std::transform创建并返回一个新向量,其中每个分数都加上该加分值。创建一个名为
calculateAverage的函数,接收一个const std::vector<int>&,并以double类型返回平均值。使用std::accumulate计算总和,然后除以向量大小。创建一个名为
printVector的函数,接收一个const std::vector<int>&,并打印所有元素,元素之间用空格分隔,最后换行。main.cpp:读取 6 个输入(每个输入各占一行):- 第一个分数(整数)
- 第二个分数(整数)
- 第三个分数(整数)
- 第四个分数(整数)
- 要搜索的分数(整数)
- 要添加的加分值(整数)
用这四个分数创建一个向量,并演示这些算法:
- 打印
Original:,后面接向量内容 - 对分数排序,并打印
Sorted:,后面接排序后的向量 - 在排序后的向量中搜索目标分数。如果找到,打印
Found <value> at index <index>。如果没有找到,打印<value> not found - 为排序后的分数加上加分值,并打印
With bonus:,后面接新的向量 - 计算并打印加分前排序后的原始分数的平均值,格式为
Average: <value>,保留 1 位小数
例如,输入 75、90、60、85、85 和 5 时:
Original: 75 90 60 85
Sorted: 60 75 85 90
Found 85 at index 2
With bonus: 65 80 90 95
Average: 77.5输入 100、80、95、70、50 和 10 时:
Original: 100 80 95 70
Sorted: 70 80 95 100
50 not found
With bonus: 80 90 105 110
Average: 86.2记得为 sort、find 和 transform 引入 <algorithm>,并为 accumulate 引入 <numeric>。使用 <iomanip> 中的 std::fixed 和 std::setprecision(1) 来格式化平均值。
亲手试试
#include <iostream>
#include <vector>
#include <iomanip>
#include "ScoreAnalyzer.h"
using namespace std;
int main() {
// 读取 6 个输入值
int score1, score2, score3, score4;
int searchTarget, bonusAmount;
cin >> score1;
cin >> score2;
cin >> score3;
cin >> score4;
cin >> searchTarget;
cin >> bonusAmount;
// TODO: 用 4 个分数创建一个 vector
// TODO: 打印 "Original:",然后打印 vector 的内容
// TODO: 将分数排序,打印 "Sorted:",然后打印排序后的 vector
// TODO: 在排序后的 vector 中查找目标分数
// 如果找到,打印 "Found <value> at index <index>"
// 如果未找到,打印 "<value> not found"
// TODO: 给排序后的分数加上 bonusAmount,打印 "With bonus:",然后打印新的 vector
// TODO: 计算并打印排序后分数的平均值(加分前)
// 使用 fixed 和 setprecision(1) 设置格式
// 按 "Average: <value>" 的格式打印
return 0;
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C++ 在线编译器