前言
C++ 标准模板库(STL)是 C++ 标准库的一部分,提供了一组通用的模板类和函数,用于实现常见的数据结构和算法。STL 的设计目标是提供高效、灵活、可复用的组件,以便开发人员能够快速地实现复杂的数据处理和算法操作。STL 主要包含以下几个部分:容器(Containers)、迭代器(Iterators)、算法(Algorithms)、函数对象(Function Objects)和适配器(Adapters)。
STL基本框架
1. 容器(Containers)
STL 提供了多种容器,每种容器都有其特定的用途和性能特征。以下是常见的 STL 容器:
-
序列容器:
- vector:动态数组,支持快速随机访问和尾部插入删除。
- deque:双端队列,支持快速随机访问和两端插入删除。
- list:双向链表,支持双向遍历和任意位置插入删除。
- forward_list:单向链表,支持单向遍历和任意位置插入删除。
-
关联容器:
- set:有序集合,元素唯一且自动排序。
- multiset:有序多重集合,元素可以重复且自动排序。
- map:有序映射,键值对集合,键唯一且自动排序。
- multimap:有序多重映射,键可以重复且自动排序。
-
无序关联容器(C++11 引入):
- unordered_set:无序集合,元素唯一,无序存储。
- unordered_multiset:无序多重集合,元素可以重复,无序存储。
- unordered_map:无序映射,键值对集合,键唯一,无序存储。
- unordered_multimap:无序多重映射,键可以重复,无序存储。
-
适配器容器:
- stack:栈,基于 deque 或 vector 实现的后进先出(LIFO)容器适配器。
- queue:队列,基于 deque 或 list 实现的先进先出(FIFO)容器适配器。
- priority_queue:优先队列,基于 vector 实现的优先级队列容器适配器。
2. 迭代器(Iterators)
迭代器是一种广义指针,提供了对容器和容器元素的通用访问方法。STL 中的算法通过迭代器来操作容器,将算法与特定容器的实现解耦。迭代器分为输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器,每种迭代器支持不同的操作能力。
3. 算法(Algorithms)
STL 提供了大量的算法,涵盖了排序、搜索、数值操作、生成和修改序列等常见任务。这些算法可以直接应用于容器,也可以通过迭代器应用于数组或其他数据结构。一些常见的算法包括:
- 查找和排序:
find
,count
,sort
,binary_search
,merge
等。 - 修改和操作:
copy
,transform
,replace
,fill
,swap
,reverse
等。 - 数值操作:
accumulate
,inner_product
,partial_sum
,adjacent_difference
等。
4. 函数对象(Function Objects)
函数对象(Functors)是可以像函数一样调用的对象,它们可以作为算法的参数传递,用于自定义操作。STL 提供了多个内置的函数对象,如比较器(less
, greater
)、算术操作(plus
, minus
)、逻辑操作(logical_and
, logical_or
)等。
5. 适配器(Adapters)
适配器提供了对现有组件的重新包装,使其能够符合不同的接口需求。STL 中常见的适配器包括容器适配器(如 stack、queue、priority_queue)和迭代器适配器(如 reverse_iterator)。
示例代码
以下是一个简单示例,演示了如何使用 STL 中的一些基本组件:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// 使用 vector 容器存储整数
std::vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6, 5};
// 使用算法对容器进行排序
std::sort(vec.begin(), vec.end());
// 使用迭代器遍历容器并输出
std::cout << "Sorted vector: ";
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 使用算法在容器中查找元素
int value = 5;
auto iter = std::find(vec.begin(), vec.end(), value);
if (iter != vec.end()) {
std::cout << "Found " << value << " at index " << std::distance(vec.begin(), iter) << std::endl;
} else {
std::cout << value << " not found in vector." << std::endl;
}
return 0;
}
STL的常用容器用法
当使用 C++ 的 STL(标准模板库)时,你会经常接触到多种容器。以下是几种常见容器的基本用法示例:
1. vector(动态数组)
#include <iostream>
#include <vector>
int main() {
// 创建一个整数类型的 vector
std::vector<int> vec;
// 在 vector 尾部添加元素
vec.push_back(10);
vec.push_back(20);
vec.push_back(30);
// 使用迭代器遍历 vector 并输出元素
std::cout << "Vector elements: ";
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 访问 vector 中的元素
std::cout << "First element: " << vec.front() << std::endl;
std::cout << "Last element: " << vec.back() << std::endl;
// 获取 vector 的大小
std::cout << "Vector size: " << vec.size() << std::endl;
// 清空 vector
vec.clear();
// 检查 vector 是否为空
if (vec.empty()) {
std::cout << "Vector is empty." << std::endl;
}
return 0;
}
2. map(有序映射)
#include <iostream>
#include <map>
int main() {
// 创建一个字符串到整数的映射
std::map<std::string, int> myMap;
// 向映射中插入键值对
myMap["one"] = 1;
myMap["two"] = 2;
myMap["three"] = 3;
// 使用迭代器遍历 map 并输出键值对
std::cout << "Map elements:" << std::endl;
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
std::cout << it->first << " => " << it->second << std::endl;
}
// 查找特定键的值
std::string key = "two";
if (myMap.find(key) != myMap.end()) {
std::cout << "Value of key '" << key << "' is " << myMap[key] << std::endl;
} else {
std::cout << "Key '" << key << "' not found in map." << std::endl;
}
return 0;
}
3. set(有序集合)
#include <iostream>
#include <set>
int main() {
// 创建一个整数类型的有序集合
std::set<int> mySet;
// 向集合中插入元素
mySet.insert(10);
mySet.insert(30);
mySet.insert(20);
mySet.insert(50);
// 使用迭代器遍历 set 并输出元素
std::cout << "Set elements: ";
for (auto it = mySet.begin(); it != mySet.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 检查集合中是否存在特定元素
int value = 30;
if (mySet.find(value) != mySet.end()) {
std::cout << value << " is found in set." << std::endl;
} else {
std::cout << value << " is not found in set." << std::endl;
}
return 0;
}
这些示例展示了 vector、map 和 set 这几种常见容器的基本用法,包括插入元素、遍历元素、访问元素以及查找元素等操作。使用 STL 的容器可以帮助你在 C++ 中高效地管理和操作数据。
总结
STL(Standard Template Library,标准模板库)是 C++ 中的一个重要部分,提供了丰富的通用模板类和函数模板,用于实现常见的数据结构和算法。它的设计目标是提供高效、灵活和可复用的程序组件,使得开发者可以更加专注于问题的解决而不是数据结构和算法的实现细节。
STL 的优点:
- 高效性:使用了模板元编程和内存分配优化,保证了高效的执行效率。
- 可移植性:STL 是 C++ 标准的一部分,保证了在不同的平台上的一致性和可移植性。
- 灵活性:通过模板的特性,STL 允许开发者根据需要进行定制和扩展。
- 复用性:提供了丰富的通用组件,可以直接在不同项目中重用。
STL 的设计理念是“一切皆为模板”,这种设计使得 C++ 开发者能够更加高效地利用现成的数据结构和算法,提升开发效率和代码质量。