⚙️ C++
Arrays (listas) em C++17: guia detalhado
STL в C++: vector, map, set и алгоритмы для начинающих
STL (Standard Template Library) — стандартная библиотека шаблонов C++. Это набор готовых контейнеров (структур данных) и алгоритмов, которые избавляют от необходимости писать всё с нуля. STL — одна из главных причин, почему C++ остаётся мощным языком.
vector: динамический массив
vector — самый используемый контейнер STL. Это умный массив, который автоматически изменяет свой размер.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// Создание вектора
vector<int> nums; // Пустой вектор
vector<string> words(5); // 5 элементов (пустые строки)
vector<int> fixed(3, 42); // {42, 42, 42}
vector<int> init = {1,2,3,4,5}; // Инициализация
// Добавление элементов
nums.push_back(10);
nums.push_back(20);
nums.push_back(30);
// Размер
cout << "Размер: " << nums.size() << endl; // 3
// Доступ по индексу
cout << nums[0] << endl; // 10 (без проверки границ)
cout << nums.at(1) << endl; // 20 (с проверкой, кидает исключение)
cout << nums.front() << endl; // 10 (первый)
cout << nums.back() << endl; // 30 (последний)
// Изменение
nums[0] = 100;
// Удаление последнего
nums.pop_back();
cout << "После pop_back: " << nums.size() << endl; // 2
// Вставка по итератору
nums.insert(nums.begin(), 5); // Вставить 5 в начало
// Удаление по итератору
nums.erase(nums.begin()); // Удалить первый
// Перебор
for (int n : nums) cout << n << " ";
cout << endl;
// Сортировка
vector<int> v = {5,2,8,1,9,3};
sort(v.begin(), v.end());
for (int n : v) cout << n << " "; // 1 2 3 5 8 9
cout << endl;
// Обратная сортировка
sort(v.begin(), v.end(), greater<int>());
for (int n : v) cout << n << " "; // 9 8 5 3 2 1
cout << endl;
// Очистить
v.clear();
cout << "Пустой: " << v.empty() << endl; // 1
return 0;
}
Алгоритмы STL
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric> // accumulate
using namespace std;
int main() {
vector<int> v = {5, 2, 8, 1, 9, 3, 7, 4, 6};
// Поиск
auto it = find(v.begin(), v.end(), 7);
if (it != v.end()) cout << "Найдено 7 на индексе: " << (it-v.begin()) << endl;
// find_if — поиск с условием
auto first_gt5 = find_if(v.begin(), v.end(), [](int n){ return n > 5; });
if (first_gt5 != v.end()) cout << "Первое > 5: " << *first_gt5 << endl; // 8
// Подсчёт
cout << "Количество 3: " << count(v.begin(), v.end(), 3) << endl; // 1
cout << "Количество > 5: " << count_if(v.begin(), v.end(), [](int n){ return n>5; }) << endl;
// Минимум и максимум
auto [minIt, maxIt] = minmax_element(v.begin(), v.end());
cout << "Min=" << *minIt << ", Max=" << *maxIt << endl; // Min=1, Max=9
// Сумма (из <numeric>)
int sum = accumulate(v.begin(), v.end(), 0);
cout << "Сумма: " << sum << endl; // 45
// Произведение
int product = accumulate(v.begin(), v.end(), 1, multiplies<int>());
cout << "Произведение: " << product << endl;
// Реверс
reverse(v.begin(), v.end());
for (int n : v) cout << n << " ";
cout << endl;
// Сортировка с лямбдой
vector<string> words = {"банан","яблоко","груша","абрикос"};
sort(words.begin(), words.end()); // По алфавиту
for (auto& w : words) cout << w << " ";
cout << endl;
sort(words.begin(), words.end(),
[](const string& a, const string& b){ return a.length() < b.length(); });
for (auto& w : words) cout << w << " "; // По длине
cout << endl;
// Удаление дубликатов
vector<int> dup = {1,2,2,3,3,3,4,5,5};
sort(dup.begin(), dup.end());
auto last = unique(dup.begin(), dup.end());
dup.erase(last, dup.end());
for (int n : dup) cout << n << " "; // 1 2 3 4 5
cout << endl;
return 0;
}
map: словарь ключ→значение
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
// map — отсортированный словарь (всегда в порядке ключей)
map<string, int> ages;
// Добавление
ages["Иван"] = 25;
ages["Мария"] = 22;
ages["Алексей"]= 30;
ages.insert({"Боб", 28});
ages.emplace("Катя", 19); // Эффективнее insert
// Доступ
cout << "Иван: " << ages["Иван"] << endl; // 25
// ages["Несуществующий"] создаст запись со значением 0!
// Безопасный доступ
auto it = ages.find("Мария");
if (it != ages.end()) {
cout << "Мария: " << it->second << endl;
}
// count для проверки существования
if (ages.count("Боб") > 0)
cout << "Боб существует" << endl;
// Перебор (всегда в алфавитном порядке ключей!)
for (const auto& [name, age] : ages) { // C++17: structured bindings
cout << name << ": " << age << " лет" << endl;
}
// Удаление
ages.erase("Боб");
cout << "Размер после удаления: " << ages.size() << endl;
// Практика: подсчёт частоты слов
string text = "java python java go java python c++";
map<string, int> freq;
// Разбиваем строку на слова
size_t pos = 0;
while ((pos = text.find(' ')) != string::npos) {
freq[text.substr(0, pos)]++;
text.erase(0, pos+1);
}
freq[text]++; // Последнее слово
cout << "
Частота слов:" << endl;
for (auto& [word, cnt] : freq)
cout << " " << word << ": " << cnt << endl;
return 0;
}
set: только уникальные элементы
#include <iostream>
#include <set>
#include <string>
using namespace std;
int main() {
// set — отсортированное множество без дубликатов
set<string> cities;
cities.insert("Москва");
cities.insert("Питер");
cities.insert("Новосибирск");
cities.insert("Москва"); // Дубликат — игнорируется
cities.insert("Питер"); // Тоже дубликат
cout << "Городов: " << cities.size() << endl; // 3
for (const auto& c : cities) cout << c << " "; // В алфавитном порядке!
cout << endl;
// Проверка наличия
if (cities.count("Москва")) cout << "Москва есть" << endl;
if (!cities.count("Лондон")) cout << "Лондона нет" << endl;
// Удаление
cities.erase("Питер");
// unordered_set: без сортировки, но быстрее (O(1) vs O(log n))
#include <unordered_set>
unordered_set<int> fastSet = {5,2,8,1,9,3};
fastSet.insert(5); // Дубликат, не добавится
// Практика: найти уникальные слова
string text = "яблоко груша яблоко банан груша апельсин";
set<string> unique_words;
size_t pos = 0, prev = 0;
while ((pos = text.find(' ', prev)) != string::npos) {
unique_words.insert(text.substr(prev, pos-prev));
prev = pos + 1;
}
unique_words.insert(text.substr(prev));
cout << "Уникальных слов: " << unique_words.size() << endl; // 4
for (auto& w : unique_words) cout << w << " ";
cout << endl;
return 0;
}
Работа со строками (string)
#include <iostream>
#include <string>
#include <sstream> // stringstream
#include <vector>
using namespace std;
int main() {
string s = "Привет, мир! Как дела?";
cout << s.length() << endl; // Длина
cout << s.find("мир") << endl; // Позиция "мир"
cout << s.substr(8, 3) << endl; // "мир" (от позиции 8, длина 3)
// Замена
string copy = s;
size_t pos = copy.find("мир");
if (pos != string::npos) copy.replace(pos, 3, "C++");
cout << copy << endl; // "Привет, C++! Как дела?"
// Разбиение строки на слова (через stringstream)
string text = "яблоко груша банан апельсин";
vector<string> words;
stringstream ss(text);
string word;
while (ss >> word) words.push_back(word);
cout << "Слов: " << words.size() << endl; // 4
for (auto& w : words) cout << w << " ";
cout << endl;
// Число в строку и обратно
string numStr = to_string(42);
int n = stoi("100");
double d = stod("3.14");
// Форматирование через ostringstream
ostringstream oss;
oss << "Имя: Иван, возраст: " << 25 << ", GPA: " << 4.5;
string formatted = oss.str();
cout << formatted << endl;
return 0;
}
Практический пример: менеджер задач
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
struct Task {
string title;
int priority; // 1-5, где 5 — наивысший
bool done;
Task(string t, int p) : title(t), priority(p), done(false) {}
};
int main() {
vector<Task> tasks;
// Добавить задачи
tasks.emplace_back("Выучить vector", 4);
tasks.emplace_back("Написать Hello World", 5);
tasks.emplace_back("Изучить классы", 3);
tasks.emplace_back("Поиграть в игры", 1);
tasks.emplace_back("Прочитать документацию", 2);
// Сортировка по приоритету (от высокого к низкому)
sort(tasks.begin(), tasks.end(),
[](const Task& a, const Task& b){ return a.priority > b.priority; });
cout << "Задачи по приоритету:" << endl;
for (auto& t : tasks) {
cout << " [" << t.priority << "] " << t.title << endl;
}
// Выполнить первую задачу
tasks[0].done = true;
// Посчитать незавершённые
int pending = count_if(tasks.begin(), tasks.end(),
[](const Task& t){ return !t.done; });
cout << "Незавершённых: " << pending << "/" << tasks.size() << endl;
// Удалить завершённые
tasks.erase(
remove_if(tasks.begin(), tasks.end(), [](const Task& t){ return t.done; }),
tasks.end()
);
cout << "После удаления выполненных: " << tasks.size() << " задач" << endl;
return 0;
}
Итого: что мы узнали
- ✅ STL — Standard Template Library: контейнеры + алгоритмы
- ✅ vector: динамический массив;
push_back,pop_back,size(),[] - ✅ map: отсортированный словарь ключ→значение;
[],find(),count() - ✅ set: отсортированное множество без дубликатов
- ✅ unordered_map/set: без сортировки, но O(1) операции
- ✅ Алгоритмы из
<algorithm>:sort,find,count,reverse,unique - ✅ Алгоритмы из
<numeric>:accumulateдля суммы/произведения - ✅ Лямбды в алгоритмах:
sort(v.begin(),v.end(),[](int a,int b){...}) - ✅
for (auto& x : container)— range-based for для всех контейнеров - ✅ C++17 structured bindings:
for (auto& [key, value] : map)