Алгоритмы STL
Часть раздела Объектно-ориентированное программирование путешествия по C++ на Coddy — урок 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);
// сумма: 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для поиска цели. Если значение найдено, верните индекс (расстояние от начала). Если не найдено, верните-1.Создайте функцию с именем
applyBonus, которая принимаетconst std::vector<int>&и сумму бонусаint. Используйтеstd::transform, чтобы создать и вернуть новый вектор, в котором к каждой оценке добавлен бонус.Создайте функцию с именем
calculateAverage, которая принимаетconst std::vector<int>&и возвращает среднее значение в видеdouble. Используйтеstd::accumulateдля вычисления суммы, а затем разделите её на размер вектора.Создайте функцию с именем
printVector, которая принимаетconst std::vector<int>&и выводит все элементы, разделенные пробелами, за которыми следует символ новой строки.main.cpp: Считайте шесть входных значений (каждое на отдельной строке):- Первая оценка (целое число)
- Вторая оценка (целое число)
- Третья оценка (целое число)
- Четвертая оценка (целое число)
- Оценка для поиска (целое число)
- Сумма бонуса для применения (целое число)
Создайте вектор с четырьмя оценками и продемонстрируйте работу алгоритмов:
- Выведите
Original:, а затем содержимое вектора - Отсортируйте оценки и выведите
Sorted:, а затем отсортированный вектор - Найдите целевую оценку в отсортированном векторе. Если она найдена, выведите
Found <value> at index <index>. Если не найдена, выведите<value> not found - Примените бонус к отсортированным оценкам и выведите
With bonus:, а затем новый вектор - Вычислите и выведите среднее значение исходных отсортированных оценок (до бонуса) в формате
Average: <value>с одним знаком после запятой
Например, при входных данных 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Не забудьте включить <algorithm> для sort, find и transform, а также <numeric> для accumulate. Используйте std::fixed и std::setprecision(1) из <iomanip> для форматирования среднего значения.
Шпаргалка
Алгоритмы 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)Эти алгоритмы работают с диапазонами итераторов, что делает их гибкими для использования с частичными диапазонами или различными типами контейнеров.
Попробуйте сами
#include <iostream>
#include <vector>
#include <iomanip>
#include "ScoreAnalyzer.h"
using namespace std;
int main() {
// Считать шесть входных значений
int score1, score2, score3, score4;
int searchTarget, bonusAmount;
cin >> score1;
cin >> score2;
cin >> score3;
cin >> score4;
cin >> searchTarget;
cin >> bonusAmount;
// TODO: Создать вектор с четырьмя оценками
// TODO: Вывести "Original:", а затем содержимое вектора
// TODO: Отсортировать оценки и вывести "Sorted:", а затем отсортированный вектор
// TODO: Найти целевую оценку в отсортированном векторе
// Если найдено, вывести "Found <value> at index <index>"
// Если не найдено, вывести "<value> not found"
// TODO: Применить бонус к отсортированным оценкам и вывести "With bonus:", а затем новый вектор
// TODO: Вычислить и вывести среднее арифметическое отсортированных оценок (до бонуса)
// Использовать fixed и setprecision(1) для форматирования
// Вывести в формате "Average: <value>"
return 0;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыСборка и компиляция C++Заголовочные файлы и файлы исходного кодаПространства имен и область видимостиВведение в ООП на C++Классы и объектыУказатель 'this'Методы (функции-члены)Атрибуты (члены данных)Основы конструкторов и деструкторовИтоги — Простой калькулятор4Свойства классов
Члены экземпляра против статическихГеттеры и сеттерыКонстантные функции-членыКлючевое слово mutableСтатические методы и переменныеДружественные функции и классыИтоги — Менеджер банковских счетов7Наследование
Основы наследованияУровни доступа при наследованииПорядок вызова конструкторов и деструкторовПереопределение методовВиртуальные функции и VTableМножественное наследованиеВиртуальное наследованиеИтоги — Иерархия сотрудников10Обзор STL
Обзор и философия STLКонтейнеры STLИтераторыАлгоритмы STLФункторы и лямбда-выраженияИтоги: частота слов13Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonFactory и Abstract FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy2Управление памятью
Стек и кучаУказатели и ссылкиДинамическая память (new/delete)Умные указатели в C++RAII в C++Итоги — Менеджер динамического массива5Инкапсуляция
Спецификаторы доступа в C++Спецификаторы доступа: подробный разборСокрытие данныхStruct против ClassВложенные и внутренние классыИтоги — Система учета студентов8Полиморфизм
Полиморфизм компиляции и времени выполненияПерегрузка функцийВиртуальные функции: повторениеЧистые виртуальные функцииАбстрактные классыПроектирование интерфейсов на C++Dynamic Casting и RTTIИтоги: Калькулятор фигур11Продвинутые концепции ООП
Композиция против наследованияМиксины через CRTPИдиома PimplСтирание типовEnum Classes и строгая типизацияОбработка исключений в ООППользовательские иерархии исключений14Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикRAII как паттерн3Конструкторы и деструкторы
Конструктор по умолчаниюПараметризованный конструкторКонструктор копированияКонструктор перемещенияСписки инициализации конструктораДелегирующие конструкторыГлубокое погружение в деструкторыПравило трех / пяти / нуляПовторение — класс String6Перегрузка операторов
Введение в перегрузку операторовПерегрузка арифметических операторовПерегрузка операторов сравненияОператоры потоковПерегрузка оператора присваиванияПерегрузка операторов [] и ()Операторы преобразования типовИтоги — класс Matrix9Шаблоны
Шаблоны функцийШаблоны классовСпециализация шаблоновВариативные шаблоныОсновы SFINAE и Type TraitsИтоги — Обобщенный контейнер