- 这里我们介绍一下 C++ 算法竞赛中的STL常用的容器和函数用法:
- 一.vector容器 二.pair容器 三.queue容器 四.deque容器 五.priority_queue容器
- 六.set容器 七.map容器 八.string容器 九.stack容器 十.tuple容器
- 一.vector容器
- 二.pair容器
- 三.queue容器
- 四.deque容器
- 五.priority_queue容器
- 六.set容器
- 七.map容器
- 八.string容器
- 九.stack容器
- 十.tuple容器
这里我们介绍一下 C++ 算法竞赛中的STL常用的容器和函数用法:
在这个C++ STL容器运用的部分,我们只简单的介绍常用的语法和运用,每一个容器的结束也都会举与容器有关的题目来实践运用。如有补充不全或者错误,还请多包涵。
一.vector容器 二.pair容器 三.queue容器 四.deque容器 五.priority_queue容器
六.set容器 七.map容器 八.string容器 九.stack容器 十.tuple容器
一.vector容器
1.1 介绍:
- 引入头文件:
#include<vector>
- 动态数组,可以随时删除和增加元素,相比于直接在局部定义数组大小,vector不会发生爆栈,对大容量存储数据很友好。
1.2 容器包含的函数(介绍常用的一些,其余的可以去百度):
函数 | 作用 |
---|---|
a.push_back(x) | 将元素添加到向量的末尾 |
a.pop_back(x) | 从向量的末尾删除元素 |
a.front(x) | 返回向量的第一个元素的引用 |
a.back(x) | 返回向量的最后一个元素的引用 |
a.size() | 返回向量中元素的数量 |
a.resize() | 更改向量的大小 |
a.insert() | 在指定位置插入元素 |
a.erase(first,last) | 删除指定范围内的元素 |
a.clear() | 删除向量中的所有元素 |
a.empty() | 检查向量是否为空 |
#include <bits/stdc++.h> //我个人喜欢用(基本上包含了所有容器)
using namespace std;
int main() {
std::vector<int> vec;
// 将元素添加到向量的末尾
vec.push_back(5); // 现在vec中有一个元素 5
// 从向量的末尾删除元素
vec.pop_back(); // 现在vec为空
// 返回向量的第一个元素的引用
vec.push_back(3);
std::cout << vec.front() << std::endl; // 输出 3
// 返回向量的最后一个元素的引用
std::cout << vec.back() << std::endl; // 输出 3
// 返回向量中元素的数量
std::cout << vec.size() << std::endl; // 输出 1
// 更改向量的大小
vec.resize(3); // 现在vec中有3个元素,值为0
// 在指定位置插入元素
vec.insert(vec.begin() + 1, 10); // 在第二个位置插入元素10
// 删除指定范围内的元素
vec.erase(vec.begin(), vec.begin() + 2); // 删除前两个元素
// 删除向量中的所有元素
vec.clear(); // 现在vec为空
// 检查向量是否为空
if (vec.empty())
{
std::cout << "Vector is empty" << std::endl;
}
return 0;
}
1.3 实践运用:
题目来源:(1211 - 数组元素的插入-东方博宜OJ (czos.cn)
#include<bits/stdc++.h> // 包含标准库头文件
using namespace std; // 使用标准命名空间
int main(){
int n;
cin>>n;
vector<int> a; // 声明一个整型向量a,用于存储输入的元素
for(int i=0;i<n;i++)
{
int k; // 定义变量k,表示当前输入的元素值
cin>>k; // 输入元素值
a.push_back(k); // 将元素值k插入到向量a的末尾
}
int x,y;
cin>>x>>y;
a.insert(a.begin()+x-1,y); // 在位置x-1处插入元素值y
//c++11基于范围循环语法
for(auto &it:a) // 遍历向量a中的所有元素
{
cout<<it<<" "; // 输出当前元素值,并跟一个空格
}
return 0;
}
二.pair容器
1.1 介绍:
- 引入头文件
#include<utility>
- pair 是一个简单的将两个数据组合成一个单元的数据结构。它常用于需要同时存储两个相关数据的情况,例如键值对或坐标等。
1.2 容器包含的函数(介绍常用的一些,其余的可以去百度):
函数 | 作用 |
---|---|
a.first | 返回存储的第一个元素的引用 |
a.second | 返回存储的第二个元素的引用 |
1.3 实践运用:
题目:输入五个学生的姓名和分数
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
int main() {
// 提示用户输入5个姓名和分数
vector<pair<string, double>> students;
for (int i = 0; i < 5; ++i) {
cout << "Enter name " << i + 1 << ": ";
string name;
cin >> name;
cout << "Enter score " << i + 1 << ": ";
double score;
cin >> score;
// 创建并初始化一个 pair 对象,并将其添加到 vector 中
students.push_back(make_pair(name, score));
}
// 输出 vector 中所有 pair 对象的元素
cout << "Students:\n";
for (const auto& student : students) {
cout << "Name: " << student.first << " - Score: " << student.second << endl;
}
return 0;
}
三.queue容器
1.1 介绍:
- 引入头文件
#include<queue>
- queue 是一个先进先出(FIFO)的数据结构,它模拟了排队的行为。元素从队列的一端进入(称为后端),并从另一端离开(称为前端)。
1.2 容器包含的函数(介绍常用的一些,其余的可以去百度):
函数 | 作用 |
---|---|
a.front() | 返回队列中第一个元素,但不删除该元素 |
a.back() | 返回队列中最后一个元素的,但不删除该元素 |
a.push(x) | 将元素 x 添加到队列的末尾 |
a.pop() | 删除队列中的第一个元素,但不返回其值 |
a.size() | 返回队列中元素的数量 |
a.empty() | 检查队列是否为空,返回 true 如果队列为空,否则返回 false |
1.3 实践运用:
#include <iostream>
#include <queue>
using namespace std;
int main() {
// 创建一个队列
queue<int> myQueue;
// 向队列中添加元素
myQueue.push(10); // 队列: 10
myQueue.push(20); // 队列: 10 20
myQueue.push(30); // 队列: 10 20 30
// 输出队列中的第一个元素
cout << "Front element: " << myQueue.front() << endl; // 输出: 10
// 输出队列中的最后一个元素
cout << "Back element: " << myQueue.back() << endl; // 输出: 30
// 删除队列中的第一个元素
myQueue.pop(); // 队列: 20 30
// 输出删除元素后队列的大小
cout << "Queue size after pop: " << myQueue.size() << endl; // 输出: 2
// 检查队列是否为空
if (myQueue.empty()) {
cout << "Queue is empty" << endl; // 不会执行
} else {
cout << "Queue is not empty" << endl; // 输出: Queue is not empty
}
return 0;
}
四.deque容器
1.1 介绍:
- 引入头文件
#include<deque>
- deque 是双端队列(Double-Ended Queue)的缩写,它是一种可以在两端进行高效插入和删除操作的动态数组。与普通的队列不同,deque 允许在头部和尾部都进行快速的插入和删除。
1.2 容器包含的函数(介绍常用的一些,其余的可以去百度):
函数 | 作用 |
---|---|
a.push_front(x) | 将元素 x 添加到双端队列的前端 |
a.push_back(x) | 将元素 x 添加到双端队列的后端 |
a.back() | 返回双端队列中最后一个元素的,但不删除该元素 |
a.front() | 返回双端队列中第一个元素的,但不删除该元素 |
a.pop_back() | 删除双端队列中的最后一个元素 |
a.pop_front() | 删除双端队列中的第一个元素 |
empty() | 检查双端队列是否为空,返回 true 如果队列为空,否则返回 false |
a.size() | 返回双端队列中元素的数量 |
a.clear() | 清空双端队列,移除所有元素 |
1.3 实践运用:
#include <iostream>
#include <deque>
using namespace std;
int main() {
// 创建一个双端队列
deque<int> myDeque;
// 向队列两端添加元素
myDeque.push_back(10); // 双端队列: [10]
myDeque.push_back(20); // 双端队列: [10, 20]
myDeque.push_front(5); // 双端队列: [5, 10, 20]
// 输出队列中的第一个元素和最后一个元素
cout << "Front element: " << myDeque.front() << endl; // 输出: 5
cout << "Back element: " << myDeque.back() << endl; // 输出: 20
// 删除队列中的第一个和最后一个元素
myDeque.pop_front(); // 双端队列: [10, 20]
myDeque.pop_back(); // 双端队列: [10]
// 输出删除元素后队列的大小
cout << "Deque size after pop: " << myDeque.size() << endl; // 输出: 1
// 检查队列是否为空
if (myDeque.empty()) {
cout << "Deque is empty" << endl; // 不会执行
} else {
cout << "Deque is not empty" << endl; // 输出: Deque is not empty
}
// 清空双端队列
myDeque.clear();
// 输出清空后队列的大小
cout << "Deque size after clear: " << myDeque.size() << endl; // 输出: 0
return 0;
}
五.priority_queue容器
1.1 介绍:
- 引入头文件
#include<queue>
- priority_queue 是一个优先队列,它会按照元素的优先级自动对元素进行排序。元素的优先级可以通过自定义的比较函数或元素自身的特性来确定。
1.2 容器包含的函数(介绍常用的一些,其余的可以去百度):
函数 | 作用 |
---|---|
a.top() | 返回优先队列中的顶部元素,但不删除该元素 |
a.push() | 将元素添加到优先队列 |
a.pop() | 删除优先队列中的顶部元素 |
a.size() | 返回优先队列中的元素数量 |
a.empty() | 检查优先队列是否为空。返回 true 如果队列为空,否则返回 false |
1.3 实践运用:
#include <iostream>
#include <queue>
using namespace std;
int main() {
// 创建一个优先队列
priority_queue<int> myPriorityQueue;
// 将元素添加到优先队列
myPriorityQueue.push(30);
myPriorityQueue.push(100);
myPriorityQueue.push(25);
myPriorityQueue.push(40);
// 输出优先队列中的顶部元素
cout << "Top element: " << myPriorityQueue.top() << endl; // 输出: 100
// 删除优先队列中的顶部元素
myPriorityQueue.pop();
// 输出删除元素后优先队列的大小
cout << "Priority queue size after pop: " << myPriorityQueue.size() << endl; // 输出: 3
// 检查优先队列是否为空
if (myPriorityQueue.empty())
{
//不会执行
cout << "Priority queue is empty" << endl;
}
else
{
// 输出: Priority queue is not empty
cout << "Priority queue is not empty" << endl;
}
return 0;
}
六.set容器
1.1 介绍:
- 引入头文件
#include<set>
- set 是一种集合数据结构,它存储一组唯一的元素。set 中的元素是无序的,并且不允许重复。它提供了高效的元素插入、删除和查找操作。
1.2 容器包含的函数(介绍常用的一些,其余的可以去百度):
函数 | 作用 |
---|---|
a.begin() |
返回指向容器中第一个元素的迭代器。 |
a.end() |
返回指向容器中最后一个元素之后的位置的迭代器。 |
a.clear() |
清空容器,删除所有元素。 |
a.empty() |
检查容器是否为空。如果容器为空,则返回 true ;否则返回 false 。 |
a.size() |
返回容器中元素的数量。 |
a.insert(x) |
在容器中插入元素 x 。如果元素已存在,则不插入。返回一个指向插入位置或现有元素位置的迭代器。 |
a.erase(地址) |
删除容器中指定位置的元素。 |
a.find(x) |
在容器中查找值为 x 的元素,返回指向该元素的迭代器。如果找不到,则返回 a.end() 。 |
a.count(x) |
返回容器中值为 x 的元素的个数。 |
a.lower_bound(x) |
返回一个迭代器,指向第一个不小于 x 的元素。如果所有元素都小于 x ,则返回 a.end() 。 |
a.upper_bound(x) |
返回一个迭代器,指向第一个大于 x 的元素。如果所有元素都不大于 x ,则返回 a.end() 。 |
1.3 实践运用:
#include <iostream>
#include <set>
using namespace std;
int main() {
// 创建一个 set 容器
set<int> mySet;
// 插入元素到 set
mySet.insert(30);
mySet.insert(100);
mySet.insert(25);
mySet.insert(40);
// 输出 set 中的元素
cout << "Set elements:";
for (auto it = mySet.begin(); it != mySet.end(); ++it) {
cout << " " << *it;
}
cout << endl; // 输出: Set elements: 25 30 40 100
// 删除 set 中的元素或者也可以删除对应的地址的元素。
mySet.erase(30);//mySet.erase(mySet.begin()+1);
// 输出删除元素后 set 的大小
cout << "Set size after erase: " << mySet.size() << endl; // 输出: Set size after erase: 3
// 检查 set 是否为空
if (mySet.empty()) {
cout << "Set is empty" << endl; // 不会执行
} else {
cout << "Set is not empty" << endl; // 输出: Set is not empty
}
// 查找元素
auto it = mySet.find(25);
if (it != mySet.end()) {
cout << "Element found: " << *it << endl; // 输出: Element found: 25
} else {
cout << "Element not found" << endl;
}
return 0;
}
七.map容器
1.1 介绍:
- 引入头文件
#include<map>
- map 是一种关联容器,它将键(Key)与值(Value)关联起来。map 中的元素是按照键进行排序的,并且键必须是唯一的。它提供了高效的键值对存储和查找功能。
1.2 容器包含的函数(介绍常用的一些,其余的可以去百度):
函数 | 作用 |
---|---|
m.begin() |
返回指向容器中第一个元素的迭代器。 |
m.end() |
返回指向容器中最后一个元素之后的位置的迭代器。 |
m.clear() |
清空容器,删除所有元素。 |
m.empty() |
检查容器是否为空。如果容器为空,则返回 true ;否则返回 false 。 |
m.size() |
返回容器中元素的数量。 |
m.insert(pair) |
在容器中插入键值对 pair 。如果键已存在,则不插入。返回一个指向插入位置或现有元素位置的迭代器。 |
m.erase(key) |
删除容器中指定键 key 对应的元素。 |
m.find(key) |
在容器中查找键为 key 的元素,返回指向该元素的迭代器。如果找不到,则返回 m.end() 。 |
m.count(key) |
返回容器中键为 key 的元素的个数。 |
m.lower_bound(key) |
返回一个迭代器,指向第一个不小于 key 的元素。如果所有元素都小于 key ,则返回 m.end() 。 |
m.upper_bound(key) |
返回一个迭代器,指向第一个大于 key 的元素。如果所有元素都不大于 key ,则返回 m.end() 。 |
1.3 实践运用:
#include <iostream>
#include <map>
using namespace std;
int main() {
map<int, string> map;
// 插入元素
map.insert({1, "One"});
map.insert({2, "Two"});
map.insert({3, "Three"});
// 直接输出键值对
cout << "1: " << map[1] << endl; //One
cout << "2: " << map[2] << endl;//Two
cout << "3: " << map[3] << endl;//Three
// 清空操作
map.clear();
// Map is empty: true
cout << "Map is empty: " << (map.empty() ? "true" : "false") << endl;
// 大小和查找操作
// Map size: 0
cout << "Map size: " << map.size() << endl;
// Key 2 found: false
cout << "Key 2 found: " << (map.find(2) != map.end() ? "true" : "false") << endl;
// 计数操作
// Count of key 3: 0
cout << "Count of key 3: " << map.count(3) << endl;
// lower_bound 和 upper_bound 操作
map.insert({1, "One"});
map.insert({2, "Two"});
map.insert({3, "Three"});
auto lower = map.lower_bound(2);
auto upper = map.upper_bound(2);
// Lower bound of key 2: 2
cout << "Lower bound of key 2: " << lower->first << endl;
// Upper bound of key 2: 3
cout << "Upper bound of key 2: " << upper->first << endl;
return 0;
}
八.string容器
1.1 介绍:
- string 是表示字符串的容器,它提供了对字符串的各种操作,如拼接、截取、查找等。string 实现了高效的字符串处理功能,并且可以自动管理字符串的内存。
1.2 容器包含的函数(介绍常用的一些,其余的可以去百度):
1.3 实践运用:
九.stack容器
1.1 介绍:
- 引入头文件
#include<stack>
- stack 是一种后进先出(LIFO)的数据结构,它模拟了栈的行为。元素只能从栈顶进行插入和删除操作,最后进入栈的元素最先被取出。
1.2 容器包含的函数(介绍常用的一些,其余的可以去百度):
函数 | 作用 |
---|---|
a.push(x) |
将元素 x 压入栈。 |
a.pop() |
弹出栈顶的元素,不返回任何值。 |
a.top() |
返回栈顶元素的引用,但不删除该元素。 |
a.empty() |
检查栈是否为空。如果容器为空,则返回 true ;否则返回 false 。 |
a.size() |
返回栈中元素的数量。 |
1.3 实践运用:
#include <iostream>
#include <stack>
using namespace std;
int main() {
stack<int> a;
// push 元素
a.push(1);
a.push(2);
a.push(3);
// pop 元素
a.pop();
// top 元素
cout << "Top element: " << a.top() << endl; // Top element: 2
// 检查是否为空
cout << "Is stack empty: " << (a.empty() ? "true" : "false") << endl; // Is stack empty: false
// 返回容器中元素的数量
cout << "Size of stack: " << a.size() << endl; // Size of stack: 2
return 0;
}
十.tuple容器
1.1 介绍:
#include<tuple>
- tuple 是一种固定大小的元组数据结构,可以存储多个不同类型的元素。它提供了一种方便的方式来组合多个相关的数据项,并可以通过索引或类型推导来访问这些元素。
1.2 容器包含的函数(介绍常用的一些,其余的可以去百度):
函数 | 作用 |
---|---|
make_tuple(...) |
创建并返回一个新的 tuple 对象,其中包含传入的参数。 |
tie(...) |
创建一个包含传入参数的引用 tuple 对象。 |
get<i>(tuple) |
返回 tuple 中索引为 i 的元素的引用,索引从 0 开始。 |
tuple_size<decltype(tuple)>::value |
返回 tuple 中元素的数量。 |
tuple_element<i, decltype(tuple)>::type |
返回 tuple 中索引为 i 的元素的类型,索引从 0 开始。 |
1.3 实践运用:
#include <iostream>
#include <tuple>
using namespace std;
int main() {
// 创建一个 tuple 对象
auto my_tuple = make_tuple(10, 'a', 3.14);
// 使用 tie 创建引用 tuple
int a;
char b;
double c;
tie(a, b, c) = my_tuple; // 将 my_tuple 中的值解包到 a、b、c 中
// 访问 tuple 元素
cout << "Tuple elements: " << get<0>(my_tuple) << ", " << get<1>(my_tuple) << ", " << get<2>(my_tuple) << endl; // 使用 get<> 访问 tuple 的元素值
// 获取 tuple 大小
cout << "Size of tuple: " << tuple_size<decltype(my_tuple)>::value << endl; // 输出 tuple 的大小
// 获取 tuple 元素类型
typedef tuple_element<1, decltype(my_tuple)>::type TypeB;
cout << "Type of tuple element at index 1: " << typeid(TypeB).name() << endl; // 输出 tuple 第二个元素的类型
return 0;
}
能认认真真看到这里相信你一定比我强!!!