Menu
CoddyTech

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)

这些算法接受迭代器范围,而不是直接接受容器,因此足够灵活,可以使用相同的代码处理部分范围或不同类型的容器。

challenge icon

挑战

简单

让我们使用 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 个输入(每个输入各占一行):
    1. 第一个分数(整数)
    2. 第二个分数(整数)
    3. 第三个分数(整数)
    4. 第四个分数(整数)
    5. 要搜索的分数(整数)
    6. 要添加的加分值(整数)

    用这四个分数创建一个向量,并演示这些算法:

    1. 打印 Original:,后面接向量内容
    2. 对分数排序,并打印 Sorted:,后面接排序后的向量
    3. 在排序后的向量中搜索目标分数。如果找到,打印 Found <value> at index <index>。如果没有找到,打印 <value> not found
    4. 为排序后的分数加上加分值,并打印 With bonus:,后面接新的向量
    5. 计算并打印加分前排序后的原始分数的平均值,格式为 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;
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: C++ 在线编译器