C++ 学习杂记00:标准模板库(STL)

张开发
2026/4/21 1:13:17 15 分钟阅读

分享文章

C++ 学习杂记00:标准模板库(STL)
概述C 标准模板库Standard Template LibrarySTL是C标准库的核心组成部分提供了一组通用的模板类和函数实现了常见的数据结构和算法。STL基于泛型编程思想具有高度可复用性和效率。核心组件1. 容器Containers容器用于存储和管理数据集合。顺序容器#include iostream #include vector #include deque #include list #include array // vector - 动态数组 void vector_example() { std::vectorint vec {1, 2, 3, 4, 5}; // 添加元素 vec.push_back(6); vec.insert(vec.begin(), 0); // 访问元素 std::cout 第一个元素: vec.front() std::endl; std::cout 最后一个元素: vec.back() std::endl; std::cout 第三个元素: vec[2] std::endl; // 不检查边界 std::cout 第三个元素: vec.at(2) std::endl; // 检查边界 // 遍历 for (int num : vec) { std::cout num ; } std::cout std::endl; // 容量信息 std::cout 大小: vec.size() std::endl; std::cout 容量: vec.capacity() std::endl; } // deque - 双端队列 void deque_example() { std::dequeint dq {2, 3, 4}; // 两端操作 dq.push_front(1); dq.push_back(5); for (int num : dq) { std::cout num ; } std::cout std::endl; } // list - 双向链表 void list_example() { std::listint lst {1, 2, 3, 4, 5}; // 插入删除 auto it std::next(lst.begin(), 2); // 指向第三个元素 lst.insert(it, 99); lst.erase(std::prev(lst.end())); // 删除最后一个元素 // 链表特有操作 lst.sort(); lst.unique(); for (int num : lst) { std::cout num ; } std::cout std::endl; }关联容器#include set #include map #include unordered_set #include unordered_map // set - 有序集合 void set_example() { std::setint s {5, 2, 8, 1, 9}; // 插入 s.insert(3); s.insert(5); // 重复元素不会插入 // 查找 auto it s.find(3); if (it ! s.end()) { std::cout 找到元素: *it std::endl; } // 遍历有序 for (int num : s) { std::cout num ; } std::cout std::endl; // 多重集合允许重复 std::multisetint ms {1, 2, 2, 3, 3, 3}; std::cout 数字3的出现次数: ms.count(3) std::endl; } // map - 有序映射 void map_example() { std::mapstd::string, int scores { {Alice, 90}, {Bob, 85}, {Charlie, 95} }; // 插入 scores[David] 88; scores.insert({Eve, 92}); // 访问 std::cout Alice的分数: scores[Alice] std::endl; std::cout Bob的分数: scores.at(Bob) std::endl; // 遍历 for (const auto pair : scores) { std::cout pair.first : pair.second std::endl; } // 查找 auto it scores.find(Charlie); if (it ! scores.end()) { std::cout 找到Charlie分数: it-second std::endl; } } // 无序容器哈希表 void unordered_example() { std::unordered_mapstd::string, int word_count; // 统计单词出现次数 std::string text apple banana apple orange banana apple; std::string word; std::istringstream iss(text); while (iss word) { word_count[word]; } for (const auto pair : word_count) { std::cout pair.first : pair.second std::endl; } }容器适配器#include stack #include queue void adapter_example() { // stack - 栈 std::stackint stk; stk.push(1); stk.push(2); stk.push(3); std::cout 栈顶元素: stk.top() std::endl; stk.pop(); std::cout 弹出后栈顶: stk.top() std::endl; // queue - 队列 std::queueint q; q.push(1); q.push(2); q.push(3); std::cout 队首: q.front() std::endl; std::cout 队尾: q.back() std::endl; q.pop(); std::cout 出队后队首: q.front() std::endl; // priority_queue - 优先队列 std::priority_queueint pq; pq.push(3); pq.push(1); pq.push(4); pq.push(2); std::cout 优先队列最大堆: ; while (!pq.empty()) { std::cout pq.top() ; pq.pop(); } std::cout std::endl; // 最小堆 std::priority_queueint, std::vectorint, std::greaterint min_pq; min_pq.push(3); min_pq.push(1); min_pq.push(4); std::cout 最小堆: min_pq.top() std::endl; }2. 迭代器Iterators迭代器用于访问容器中的元素提供统一的遍历接口。#include iterator #include algorithm void iterator_example() { std::vectorint vec {1, 2, 3, 4, 5}; // 不同类型迭代器 std::cout 顺序遍历: ; for (auto it vec.begin(); it ! vec.end(); it) { std::cout *it ; } std::cout std::endl; std::cout 逆序遍历: ; for (auto it vec.rbegin(); it ! vec.rend(); it) { std::cout *it ; } std::cout std::endl; // 迭代器类别 std::vectorint::iterator random_it vec.begin(); // 随机访问迭代器 std::listint::iterator bidirectional_it; // 双向迭代器 // 迭代器操作 auto it vec.begin(); std::advance(it, 2); // 前进2个位置 std::cout 前进2位: *it std::endl; // 计算距离 auto dist std::distance(vec.begin(), vec.end()); std::cout 容器大小: dist std::endl; }3. 算法AlgorithmsSTL提供丰富的通用算法大多数定义在algorithm头文件中。#include algorithm #include numeric void algorithm_example() { std::vectorint vec {5, 2, 8, 1, 9, 3, 7, 4, 6}; // 排序算法 std::sort(vec.begin(), vec.end()); std::cout 排序后: ; for (int num : vec) std::cout num ; std::cout std::endl; // 查找算法 auto it std::find(vec.begin(), vec.end(), 7); if (it ! vec.end()) { std::cout 找到7位置: std::distance(vec.begin(), it) std::endl; } // 二分查找需先排序 bool found std::binary_search(vec.begin(), vec.end(), 5); std::cout 二分查找5: (found ? 找到 : 未找到) std::endl; // 计数 int count_5 std::count(vec.begin(), vec.end(), 5); std::cout 数字5出现次数: count_5 std::endl; // 累加 int sum std::accumulate(vec.begin(), vec.end(), 0); std::cout 总和: sum std::endl; // 变换 std::vectorint squared; std::transform(vec.begin(), vec.end(), std::back_inserter(squared), [](int x) { return x * x; }); std::cout 平方: ; for (int num : squared) std::cout num ; std::cout std::endl; // 复制 std::vectorint copy_vec(vec.size()); std::copy(vec.begin(), vec.end(), copy_vec.begin()); // 删除和擦除模式 vec.erase(std::remove_if(vec.begin(), vec.end(), [](int x) { return x % 2 0; }), // 删除偶数 vec.end()); std::cout 删除偶数后: ; for (int num : vec) std::cout num ; std::cout std::endl; // 最大值最小值 auto max_it std::max_element(copy_vec.begin(), copy_vec.end()); auto min_it std::min_element(copy_vec.begin(), copy_vec.end()); std::cout 最大值: *max_it , 最小值: *min_it std::endl; }4. 函数对象Functors和Lambda表达式#include functional void functor_example() { // 内置函数对象 std::plusint add; std::cout 3 5 add(3, 5) std::endl; std::greaterint greater_than; std::cout 5 3? greater_than(5, 3) std::endl; // 自定义函数对象 struct Square { int operator()(int x) const { return x * x; } }; Square square; std::cout 4的平方: square(4) std::endl; // Lambda表达式 std::vectorint vec {1, 2, 3, 4, 5}; // 使用Lambda过滤偶数 std::cout 偶数: ; std::for_each(vec.begin(), vec.end(), [](int x) { if (x % 2 0) { std::cout x ; } }); std::cout std::endl; // 带捕获的Lambda int threshold 3; std::cout 大于 threshold 的数: ; std::for_each(vec.begin(), vec.end(), [threshold](int x) { if (x threshold) { std::cout x ; } }); std::cout std::endl; // Lambda排序 std::vectorstd::pairint, std::string pairs { {3, three}, {1, one}, {2, two} }; std::sort(pairs.begin(), pairs.end(), [](const auto a, const auto b) { return a.first b.first; }); std::cout 排序后: ; for (const auto p : pairs) { std::cout p.second ; } std::cout std::endl; }5. 实用工具#include utility #include tuple #include memory void utility_example() { // pair std::pairint, std::string p1 {1, Alice}; auto p2 std::make_pair(2, Bob); std::cout p1: p1.first , p1.second std::endl; std::cout p2: p2.first , p2.second std::endl; // tuple std::tupleint, std::string, double t1 {1, Apple, 2.5}; auto t2 std::make_tuple(2, Banana, 1.8); std::cout t1: std::get0(t1) , std::get1(t1) , std::get2(t1) std::endl; // 智能指针 std::unique_ptrint ptr1 std::make_uniqueint(42); std::cout unique_ptr: *ptr1 std::endl; std::shared_ptrint ptr2 std::make_sharedint(100); std::shared_ptrint ptr3 ptr2; // 共享所有权 std::cout shared_ptr use_count: ptr2.use_count() std::endl; // 移动语义 std::vectorint source {1, 2, 3, 4, 5}; std::vectorint dest std::move(source); std::cout 移动后source大小: source.size() std::endl; std::cout 移动后dest大小: dest.size() std::endl; }综合示例#include iostream #include vector #include algorithm #include string #include map // 学生信息结构 struct Student { int id; std::string name; double score; // 用于排序的比较函数 bool operator(const Student other) const { return score other.score; // 按分数降序 } }; void student_management_system() { std::vectorStudent students { {101, Alice, 85.5}, {102, Bob, 92.0}, {103, Charlie, 78.5}, {104, David, 88.0}, {105, Eve, 95.5} }; // 1. 按分数排序 std::sort(students.begin(), students.end()); std::cout 学生成绩排名:\n; for (const auto student : students) { std::cout ID: student.id , 姓名: student.name , 分数: student.score std::endl; } // 2. 查找特定学生 auto it std::find_if(students.begin(), students.end(), [](const Student s) { return s.name Charlie; }); if (it ! students.end()) { std::cout \n找到Charlie分数: it-score std::endl; } // 3. 统计分数段 int high_score std::count_if(students.begin(), students.end(), [](const Student s) { return s.score 90.0; }); std::cout \n90分以上人数: high_score std::endl; // 4. 计算平均分 double total std::accumulate(students.begin(), students.end(), 0.0, [](double sum, const Student s) { return sum s.score; }); double average total / students.size(); std::cout 平均分: average std::endl; // 5. 使用map按ID快速查找 std::mapint, Student student_map; for (const auto student : students) { student_map[student.id] student; } int search_id 102; auto map_it student_map.find(search_id); if (map_it ! student_map.end()) { std::cout \n通过ID查找: map_it-second.name , 分数: map_it-second.score std::endl; } } int main() { std::cout STL综合示例 \n std::endl; // 运行各个示例 std::cout 1. 容器示例: std::endl; vector_example(); std::cout std::endl; std::cout 2. 算法示例: std::endl; algorithm_example(); std::cout std::endl; std::cout 3. 函数对象和Lambda示例: std::endl; functor_example(); std::cout std::endl; std::cout 4. 学生管理系统示例: std::endl; student_management_system(); return 0; }最佳实践选择正确的容器需要随机访问vector、array频繁插入删除list、deque需要自动排序set、map需要快速查找unordered_set、unordered_map使用算法代替手写循环// 不好 for (int i 0; i vec.size(); i) { if (vec[i] threshold) { // 处理 } } // 更好 std::for_each(vec.begin(), vec.end(), [threshold](int x) { if (x threshold) { // 处理 } });使用智能指针管理资源// 避免 MyClass* obj new MyClass(); // ... 使用obj delete obj; // 推荐 auto obj std::make_uniqueMyClass(); // 自动释放内存优先使用迭代器而不是索引// 可移植性更好 for (auto it vec.begin(); it ! vec.end(); it) { // 使用*it }总结STL是C的核心特性之一提供了强大而高效的工具集。掌握STL可以显著提高开发效率写出更简洁、更安全、更高效的代码。建议通过实际项目不断练习深入理解各个组件的特性和适用场景。

更多文章