C++ Standard Template Library (STL) 是 C++ 标准库的一个重要组成部分,提供了一系列高效、通用、可复用的模板类和函数。STL 极大地提高了 C++ 程序员的开发效率,使得许多常见的数据结构和算法问题可以通过简单的几行代码解决。本文将详细介绍 STL 中的一些常见组件及其使用方法。
容器(Containers) 向量(vector) std::vector
是最常用的动态数组实现,支持随机访问,能够在运行时动态地增加和减少元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <vector> #include <iostream> int main () { std::vector<int > vec; vec.push_back (1 ); vec.push_back (2 ); vec.push_back (3 ); for (int i = 0 ; i < vec.size (); ++i) { std::cout << vec[i] << " " ; } std::cout << std::endl; for (const auto &elem : vec) { std::cout << elem << " " ; } std::cout << std::endl; return 0 ; }
列表(list) std::list
是一个双向链表,不支持随机访问,但插入和删除元素非常高效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <list> #include <iostream> int main () { std::list<int > lst = {1 , 2 , 3 }; for (auto it = lst.begin (); it != lst.end (); ++it) { std::cout << *it << " " ; } std::cout << std::endl; lst.push_back (4 ); lst.insert (lst.begin (), 0 ); auto it = lst.find (2 ); if (it != lst.end ()) { lst.erase (it); } for (const auto &elem : lst) { std::cout << elem << " " ; } std::cout << std::endl; return 0 ; }
映射(map) std::map
是一个关联数组,它存储的元素是键值对,并且按键进行排序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <map> #include <iostream> int main () { std::map<std::string, int > ages; ages["Alice" ] = 25 ; ages["Bob" ] = 30 ; std::cout << "Alice's age: " << ages["Alice" ] << std::endl; auto it = ages.find ("Bob" ); if (it != ages.end ()) { std::cout << "Bob's age: " << it->second << std::endl; } for (const auto &pair : ages) { std::cout << pair.first << ": " << pair.second << std::endl; } return 0 ; }
算法(Algorithms) STL 提供了一系列高效的算法,这些算法通常独立于容器类型,通过迭代器操作数据。
排序(sort) std::sort
是最常用的排序算法,可以对数组或容器进行排序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <vector> #include <algorithm> #include <iostream> int main () { std::vector<int > nums = {3 , 1 , 4 , 1 , 5 , 9 , 2 , 6 , 5 , 3 , 5 }; std::sort (nums.begin (), nums.end ()); for (int num : nums) { std::cout << num << " " ; } std::cout << std::endl; return 0 ; }
查找(find) std::find
用于在容器中查找特定元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <vector> #include <algorithm> #include <iostream> int main () { std::vector<int > nums = {1 , 2 , 3 , 4 , 5 }; auto it = std::find (nums.begin (), nums.end (), 3 ); if (it != nums.end ()) { std::cout << "Found " << *it << std::endl; } else { std::cout << "Not found" << std::endl; } return 0 ; }
std::transform
用于对容器中的每个元素应用一个函数,并产生一个新的容器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <vector> #include <algorithm> #include <iterator> #include <iostream> int main () { std::vector<int > nums = {1 , 2 , 3 , 4 , 5 }; std::vector<int > squares; squares.reserve (nums.size ()); std::transform (nums.begin (), nums.end (), std::back_inserter (squares), [](int x) { return x * x; }); for (int square : squares) { std::cout << square << " " ; } std::cout << std::endl; return 0 ; }
C++ STL(Standard Template Library)除了上述常见的容器如 vector
、list
和 map
之外,还提供了其他一些非常有用的容器。以下是其中一些容器的简要说明:
1. set
set
是一个包含唯一元素的容器,它通常使用红黑树实现,元素会自动按键排序。你不能在 set
中插入重复的元素。set
中的每个元素只能出现一次。
2. multiset
与 set
类似,multiset
也包含按键排序的元素,但 multiset
允许元素重复出现,即它可以包含多个相同的元素。
3. unordered_set
unordered_set
是一个不包含重复元素的容器,但它不保证元素的排序。它通常使用哈希表实现,因此插入、删除和查找操作的时间复杂度可以接近 O(1)。
4. unordered_multiset
unordered_multiset
与 unordered_set
类似,但它允许元素重复出现。它不保证元素的排序,并且通常使用哈希表实现。
5. deque
deque
(双端队列)是一个支持在两端高效插入和删除元素的容器。与 vector
不同,deque
并没有将所有元素存储在连续的内存中,因此它不能保证随机访问的常数时间复杂度。
6. stack
stack
是一个后进先出(LIFO)的容器适配器,它提供了栈的基本操作,如 push
(入栈)、pop
(出栈)和 top
(查看栈顶元素)。stack
通常使用 deque
作为底层容器。
7. queue
queue
是一个先进先出(FIFO)的容器适配器,它提供了队列的基本操作,如 push
(入队)、pop
(出队)和 front
(查看队首元素)。queue
通常使用 deque
作为底层容器。
8. priority_queue
priority_queue
是一个允许用户根据元素的优先级进行插入和删除操作的容器适配器。元素的优先级通过比较函数确定,优先级最高的元素总是位于队列的前端。priority_queue
通常使用 vector
和 make_heap
算法作为底层实现。
这些容器提供了不同的功能和性能特性,你可以根据具体的需求选择合适的容器来解决问题。需要注意的是,除了 stack
、queue
和 priority_queue
是容器适配器外,其他容器都是直接可用的数据结构。容器适配器是对其他容器的封装,提供了特定用途的接口。