标准模板库(STL)
1. 六大组件
容器(Containers):
- 用于存储和管理数据集合的数据结构,如
vector
、list
、map
等。 - 提供了数据的组织、访问和修改的方法。
迭代器(Iterators):
- 用于遍历容器中的元素。
- 迭代器是一个类,它封装了指针,并提供类似指针的行为。
算法(Algorithms):
- 提供了一系列通用的算法,如排序、搜索、变换等。
- 算法通常接受迭代器作为参数,使其可以操作各种容器。
仿函数(Functors):
- 是可以像函数一样使用的类的实例。
- 它们通常重载了函数调用操作符
operator()
。
适配器(Adapters):
- 用于修改容器、迭代器或函数的行为。
- 包括迭代器适配器、函数适配器等。
空间配置器(Allocators):
- 用于管理动态内存的分配和释放。
- 控制容器内部如何分配和释放内存。
2. 容器及使用
容器是STL中用于存储数据的组件,它们提供了一系列的模板类,用于存储和管理数据集合。容器可以分为序列容器(如vector
、deque
、list
、array
)、关联容器(如set
、map
)、容器适配器(如stack
、queue
、priority_queue
)等。
- 用法:容器通常提供构造函数、迭代器、成员函数(如
size()
、empty()
、push_back()
等)来管理数据。
3. 迭代器
迭代器是STL中用于遍历容器元素的工具。迭代器可以指向容器中的某个元素,支持前进、后退、元素访问等操作。
- 用法:通过调用容器的
begin()
和end()
成员函数获取迭代器,然后使用循环结构遍历容器。
4. 空间配置器及其使用
空间配置器负责容器内部的内存分配和释放。STL提供了默认的空间配置器allocator
,也可以自定义空间配置器。
- 用法:通过调用空间配置器的
allocate()
和deallocate()
成员函数来分配和释放内存。容器构造时可以指定使用的空间配置器。
5. 算法
STL提供了大量的算法,这些算法可以对容器中的元素进行操作,如排序、搜索、变换等。
- 用法:直接调用STL算法,并将容器的迭代器作为参数传递。例如,使用
sort()
算法对vector
进行排序。
6. 仿函数
仿函数是一类特殊的对象,它们重载了函数调用操作符,可以像函数一样被调用。
- 用法:创建仿函数对象,并像调用函数一样使用它们。例如,使用
plus<int>()
来计算两个整数的和。
7. 适配器
适配器是一种修改已有组件行为的工具,包括迭代器适配器、函数适配器等。
- 用法:使用适配器来改变迭代器的行为,或者将函数或仿函数转换成另一种形式。例如,使用
bind
来绑定函数的某些参数,或者使用mem_fn
来调用类的成员函数。
容器实现
由于要求每个容器都展示多种操作,我会为每个容器编写一个示例代码,展示它们的常用操作。为了简化代码,我将在代码中省略std::
前缀,并在开头声明命名空间using namespace std;
。
1. 序列式容器
vector
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec = {1, 2, 3, 4, 5};
// 插入
vec.insert(vec.begin() + 2, 6); // 在索引2的位置插入6
// 删除
vec.erase(vec.begin() + 2); // 删除索引2的元素
// 修改
vec[2] = 10; // 修改索引2的元素为10
// 判断是否为空
bool isEmpty = vec.empty() ? true : false;
// 查找
auto it = find(vec.begin(), vec.end(), 4);
// 排序
sort(vec.begin(), vec.end());
// 逆序
reverse(vec.begin(), vec.end());
// 清空
clear(vec);
// 迭代器操作
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
deque
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> deq = {1, 2, 3, 4, 5};
// 插入
deq.push_back(6);
deq.push_front(0);
// 删除
deq.pop_back();
deq.pop_front();
// 修改
deq[2] = 10;
// 判断是否为空
bool isEmpty = deq.empty() ? true : false;
// 查找
it = find(deq.begin(), deq.end(), 4);
// 迭代器操作
for (auto it = deq.rbegin(); it != deq.rend(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
list
#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> lst = {1, 2, 3, 4, 5};
// 插入
lst.insert(lst.begin(), 0);
lst.insert(++lst.begin(), 6);
// 删除
lst.erase(++lst.begin()); // 删除第二个元素
// 修改
*(++lst.begin()) = 10; // 修改第二个元素为10
// 判断是否为空
bool isEmpty = lst.empty() ? true : false;
// 查找
auto it = find(lst.begin(), lst.end(), 4);
// 迭代器操作
for (auto it = lst.rbegin(); it != lst.rend(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
2. 关联式容器
set
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> s = {1, 2, 3, 4, 5};
// 插入
s.insert(6);
// 删除
s.erase(3);
// 修改
// Set不提供直接修改元素的接口,需要删除后重新插入
// 判断是否为空
bool isEmpty = s.empty() ? true : false;
// 查找
auto it = s.find(4);
// 迭代器操作
for (auto it = s.rbegin(); it != s.rend(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
multiset
#include <iostream>
#include <set>
using namespace std;
int main() {
multiset<int> ms = {1, 2, 2, 3, 4};
// 插入
ms.insert(5);
// 删除
ms.erase(ms.find(2)); // 删除一个2
// 判断是否为空
bool isEmpty = ms.empty() ? true : false;
// 查找
auto it = find(ms.begin(), ms.end(), 4);
// 迭代器操作
for (auto it = ms.rbegin(); it != ms.rend(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
map
#include <iostream>
#include <map>
using namespace std;
int main() {
map<int, string> mp = {{1, "one"}, {2, "two"}, {3, "three"}};
// 插入
mp.insert({4, "four"});
// 删除
mp.erase(2);
// 修改
mp[3] = "three modified";
// 判断是否为空
bool isEmpty = mp.empty() ? true : false;
// 查找
auto it = mp.find(3);
// 迭代器操作
for (auto it = mp.rbegin(); it != mp.rend(); ++it) {
cout << it->first << ": " << it->second << " ";
}
cout << endl;
return 0;
}
multimap
#include <iostream>
#include <map>
using namespace std;
int main() {
multimap<int, string> mmp = {{1, "one"}, {2, "two"}, {2, "two again"}};
// 插入
mmp.insert({3, "three"});
// 删除
mmp.erase(2); // 删除所有键为2的元素
// 判断是否为空
bool isEmpty = mmp.empty() ? true : false;
// 查找
auto range = mmp.equal_range(2);
// 迭代器操作
for (auto it = range.first; it != range.second; ++it) {
cout << it->first << ": " << it->second << " ";
}
cout << endl;
return 0;
}
请注意,这些示例代码展示了每个容器的基本操作,包括插入、删除、修改(如果支持)、查找、判断是否为空、迭代器操作和打印。由于set
和map
是有序容器,它们的元素会自动排序。multiset
和multimap
允许重复的元素。在实际使用中,你可能需要根据具体需求调整这些操作。
作者:
hwaityd
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。