C++标准模板库(STL):容器、迭代器与算法
容器
STL中的容器是用来存储和管理数据的类模板,提供了多种数据结构来实现不同的存储需求。常见的容器有:向量、列表、队列、栈、集合和映射等。
- 向量(vector)
vector是一个动态数组,可以在末尾插入元素,支持随机访问。其大小是可变的。
#include <vector>
std::vector<int> v = {1, 2, 3, 4};
v.push_back(5); // 插入元素
for (int x : v) {
std::cout << x << " "; // 遍历输出
}
- 列表(list)
list是双向链表,适合于在两端插入和删除元素。它不支持随机访问。
#include <list>
std::list<int> l = {1, 2, 3};
l.push_back(4); // 插入元素
l.push_front(0); // 在前端插入
- 队列(queue)
queue是一个先进先出的容器,支持在队尾插入元素,在队头删除元素。
#include <queue>
std::queue<int> q;
q.push(1);
q.push(2);
q.pop(); // 删除队头元素
- 栈(stack)
stack是一个先进后出的容器,支持在栈顶插入元素和删除元素。
#include <stack>
std::stack<int> s;
s.push(10);
s.push(20);
s.pop(); // 弹出栈顶元素
- 集合(set)
set是一个不允许重复元素的容器,元素会自动排序。
#include <set>
std::set<int> s = {1, 2, 3};
s.insert(4); // 插入元素
- 映射(map)
map是一个存储键值对的容器,元素按键排序。每个键唯一。
#include <map>
std::map<int, std::string> m;
m[1] = "One"; // 插入键值对
m[2] = "Two";
容器的基本使用与操作
- 插入
不同容器提供了不同的插入方式,如push_back、insert等。
v.push_back(10); // 向vector添加元素
l.push_front(0); // 向list添加元素
- 删除
可以使用erase删除容器中的元素。
v.erase(v.begin() + 1); // 删除vector中的元素
- 遍历
通过迭代器或范围基于for循环遍历容器。
for (int x : v) {
std::cout << x << " ";
}
迭代器
迭代器是STL中用于访问容器元素的对象。它类似于指针,提供了一种统一的方式来遍历容器。
- 迭代器的基本概念
迭代器是指向容器中元素的指针,支持解引用、前进和后退等操作。
std::vector<int>::iterator it = v.begin();
std::cout << *it << std::endl; // 解引用
- 常用的迭代器操作
- 前进(++):使迭代器指向下一个元素。
- 后退(–):使迭代器指向上一个元素。
- 解引用(*):访问当前元素的值。
for (auto it = v.begin(); it != v.end(); ++it) {
std::cout << *it << " ";
}
算法
STL提供了许多常用的算法,涵盖排序、查找、数学运算等。
- 排序算法(sort、reverse、find、binary_search)
sort:对容器进行排序。reverse:反转容器中的元素顺序。find:查找容器中某个元素。binary_search:在已排序的容器中进行二分查找。
std::sort(v.begin(), v.end()); // 排序
std::reverse(v.begin(), v.end()); // 反转
auto it = std::find(v.begin(), v.end(), 3); // 查找元素3
bool found = std::binary_search(v.begin(), v.end(), 3); // 二分查找
- 数学算法(accumulate、min、max)
accumulate:计算容器元素的累积值。min、max:返回容器中的最小值或最大值。
int sum = std::accumulate(v.begin(), v.end(), 0); // 计算累积和
int minimum = std::min(3, 5); // 求最小值
int maximum = std::max(3, 5); // 求最大值
- 集合算法(set_union、set_intersection)
set_union:求两个集合的并集。set_intersection:求两个集合的交集。
std::set<int> set1 = {1, 2, 3};
std::set<int> set2 = {3, 4, 5};
std::set<int> result;
std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), std::inserter(result, result.begin()));
函数对象与Lambda表达式
函数对象和Lambda表达式是C++中函数式编程的重要部分,用于传递和使用函数。
- 函数对象的概念与使用
函数对象是重载了()操作符的类,可以像普通函数一样调用。
class Multiply {
public:
int operator()(int x, int y) { return x * y; }
};
int main() {
Multiply multiply;
std::cout << multiply(2, 3) << std::endl; // 输出6
}
- Lambda表达式的定义与应用
Lambda表达式是一种匿名函数,可以在需要函数的地方直接定义。
auto add = [](int a, int b) { return a + b; };
std::cout << add(2, 3) << std::endl; // 输出5
Lambda表达式可以捕获外部变量,并将其传递给函数:
int x = 10;
auto captureX = [x](int y) { return x + y; };
std::cout << captureX(5) << std::endl; // 输出15
总结
STL(标准模板库)是C++的核心组件之一,提供了丰富的容器、迭代器、算法、函数对象和Lambda表达式,使得开发者能够高效地处理数据。掌握STL不仅能够减少代码的复杂性,还能提高代码的性能和可维护性。通过合理选择和使用容器、迭代器以及算法,你将能够编写出更加简洁和高效的C++程序。