在线手册参考
C++ STL(标准模板库)是一组标准的 C++ 库,包含了许多常用的数据结构和算法,可大大提高开发效率。以下是常用的 STL 组件:
在 C++ STL 中,vector 是一个动态数组容器,它可以自动调整大小以适应元素数量的变化。
常用操作如下:
#include
// 创建一个空的 vector
std::vector<int> vec;
// 创建一个含有 10 个元素,每个元素都是 0 的 vector
std::vector<int> vec1(10);
// 创建一个含有 10 个元素,每个元素都是 1 的 vector
std::vector<int> vec2(10, 1);
// 创建一个含有 3 个元素,值分别是 1,2,3 的 vector
std::vector<int> vec3 = {1, 2, 3};
// 使用迭代器创建 vector
std::vector<int> vec4(vec3.begin(), vec3.end());
注意:也可以在堆创建vector,不过会比在栈存取数据慢些
vector<int> *vec = new vector<int>{1,2,3};
std::vector<int> vec = {1, 2, 3};
// 在末尾添加一个元素 4
vec.push_back(4);
// 在位置 1 处插入元素 5
vec.insert(vec.begin() + 1, 5);
// 在末尾插入另一个 vector 的所有元素
std::vector<int> vec2 = {6, 7, 8};
vec.insert(vec.end(), vec2.begin(), vec2.end());
std::vector<int> vec = {1, 2, 3, 4, 5};
// 删除末尾的元素
vec.pop_back();
// 删除位置 2 的元素
vec.erase(vec.begin() + 2);
// 删除位置 1 到 3 的元素
vec.erase(vec.begin()+1, vec.begin()+4);
使用 []
运算符和 at()
方法都可以访问 vector 中的元素,不同之处在于:
如果使用 []
运算符访问超出 vector 范围的元素,程序将出现未定义行为
而使用 at()
方法访问超出 vector 范围的元素,程序将抛出 std::out_of_range
异常。
vec[2] // 访问第2个元素
vec.at(3) // 访问第3个元素
vec[2] = 1 // 修改第2个元素值为1
vec.at(3) = 1 // 修改第3个元素值为1
或者使用迭代器访问、修改
vector<int> vec{1, 2, 3, 4, 5};
// 使用迭代器遍历 vector 中的元素
for (auto it = vec.begin(); it != vec.end(); ++it) {
cout << *it << " ";
}
// 使用迭代器修改 vector 中的元素
for (auto it = vec.begin(); it != vec.end(); ++it) {
*it += 1;
}
// 使用范围 for 循环输出修改后的 vector 中的元素
for (auto x : vec) {
cout << x << " ";
}
C++ STL 中的 list 是一个双向链表,可以在任意位置进行插入和删除操作,而不会影响其他元素的位置。以下是 list 的常用用法
#include
std::list<int> myList; // 创建一个空的 list
std::list<int> myList = {1, 2, 3, 4, 5}; // 创建包含 1, 2, 3, 4, 5 的 list
push_back(value)
:在 list 尾部插入一个元素。push_front(value)
:在 list 头部插入一个元素。insert(pos, value)
:在指定位置插入一个元素。erase(pos)
:删除指定位置的元素。erase(start, end)
:删除从 start 到 end 之间的元素。示例代码:
#include
#include
int main() {
std::list<int> myList = {1, 2, 3};
myList.push_back(4); // 在尾部插入 4
myList.push_front(0); // 在头部插入 0
myList.insert(++myList.begin(), 5); // 在第二个位置插入 5
myList.erase(--myList.end()); // 删除最后一个元素
myList.erase(myList.begin(), myList.begin() + 2); // 删除前两个元素
for (int i : myList) {
std::cout << i << " "; // 输出: 2 5 4
}
return 0;
}
可以使用以下方法访问 list 中的元素:
front()
:返回 list 的第一个元素。back()
:返回 list 的最后一个元素。迭代器法:
// 使用迭代器遍历 list 中的元素
for (auto it = lst.begin(); it != lst.end(); ++it) {
cout << *it << " ";
}
cout << endl;
// 使用迭代器修改 list 中的元素
for (auto it = lst.begin(); it != lst.end(); ++it) {
*it += 1;
}
// 使用范围 for 循环输出修改后的 list 中的元素
for (auto x : lst) {
cout << x << " ";
}
list不能像 vector 那样使用索引或
at()
方法来访问和修改元素,只能通过迭代器来完成。此外,由于
std::list
的迭代器不支持随机访问,因此不能使用[]
运算符来访问元素。
除了上述操作,list 还支持以下操作:
size()
:返回 list 中元素的个数。empty()
:判断 list 是否为空。clear()
:清空 list 中的元素。sort()
:将 list 中的元素进行排序。std::queue
是 STL 中的队列容器,它可以用来存储一系列具有相同数据类型的元素,并支持队列的基本操作,如入队、出队、获取队首元素等。下面是 std::queue
的常用用法
std::queue<int> q; // 创建一个空队列,元素类型为 int
q.push(2); //插入元素1到队列尾部
q.pop(); // 从队列头部弹出元素
可以使用 front()
成员函数来获取队列的头部元素,但是需要注意,在调用该函数之前必须先判断队列是否为空
// 获取队列的头部元素
if (!q.empty()) {
cout << "Front element: " << q.front() << endl;
}
不支持直接修改队列内部元素,也不支持直接获取尾部元素
q.empty(); // 判断是否队列为空
q.size(); // 获取队列内元素个数
std::stack
是 C++ 标准库中的一个容器适配器,它提供了一个 LIFO(后进先出)的数据结构。std::stack
支持以下基本操作:
#include
stack<int> s; // 创建栈s
s.push(1); // 元素1从栈顶入栈
s.pop(); // 弹出出栈顶元素
s.top(); // 获取栈顶元素
不支持修改栈内元素
s.size(); // 获取栈内元素个数
s.empty(); // 判断栈是否为空。
C++ 中的 map 是一种关联容器(associative container),用于存储键值对。在 map 中,每个键唯一且与一个值相关联。
map底层是红黑树,是有序的
以下是一些常用的 map 操作
#include
std::map<std::string, int> myMap; // 创建一个空 map,键类型为 string,值类型为 int
// 创建并初始化一个 map
std::map<std::string, int> myMap2 = {{"apple", 1}, {"banana", 2}, {"orange", 3}};
myMap["key"] = value; // 插入键值对
myMap.insert(key, value)
myMap.erase(key); // 删除键为 key 的元素
myMap.clear(); // 删除所有元素
myMap["key"] = value; // 改(已经存在key的时候是修改)
int value = myMap["key"]; // 访问键对应的值
// 检查是否存在某个键
if (myMap.find("key") != myMap.end()) {
// 执行操作
}
迭代器
// 使用迭代器遍历 map
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
std::cout << it->first << " => " << it->second << '\n';
}
// 使用范围遍历语句遍历 map
for (const auto& [key, value] : myMap) {
std::cout << key << " => " << value << '\n';
}
count(key)
判断是否存在键为key的元素,存在返回1,否则返回0
std::map<std::string, int> myMap = {{"apple", 1}, {"banana", 2}, {"orange", 3}};
if (myMap.count("apple")) {
std::cout << "apple exists in myMap.\n";
} else {
std::cout << "apple does not exist in myMap.\n";
}
empty(); //是否为空
size(); // 键值对个数
find(key)
函数用于查找键为 key 的元素,如果找到了,则返回一个指向该元素的迭代器,否则返回 map 的尾部迭代器
std::map<std::string, int> myMap = {{"apple", 1}, {"banana", 2}, {"orange", 3}};
auto it = myMap.find("apple");
if (it != myMap.end()) {
std::cout << "apple found in myMap with value " << it->second << '\n';
} else {
std::cout << "apple not found in myMap.\n";
}
C++ 中的 unordered_map 是一种关联容器(associative container),与 map 类似,也用于存储键值对。
不同之处在于,unordered_map 不保证元素的顺序,并使用哈希表来实现快速查找。
unordered_map 一些操作与map基本相同
需要注意的是,unordered_map 的查询操作通常比 map 更快,但存储的元素顺序是不确定的。因此,当需要对元素进行有序访问时,应该使用 map
#include
std::unordered_map<std::string, int> myMap; // 创建一个空 unordered_map,键类型为 string,值类型为 int
// 创建并初始化一个 unordered_map
std::unordered_map<std::string, int> myMap2 = {{"apple", 1}, {"banana", 2}, {"orange", 3}};
myMap["key"] = value; // 插入键值对
myMap.erase(key); // 删除键为 key 的元素
myMap.clear(); // 删除所有元素
myMap["key"] = value; // 修改键key的值
int value = myMap["key"]; // 访问键对应的值
// 检查是否存在某个键
if (myMap.find("key") != myMap.end()) {
// 执行操作
}
迭代器
// 使用迭代器遍历 unordered_map
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
std::cout << it->first << " => " << it->second << '\n';
}
// 使用范围遍历语句遍历 unordered_map
for (const auto& [key, value] : myMap) {
std::cout << key << " => " << value << '\n';
}