DHappy 上岸没有尽头 你接受了那就是岸

C++常用容器

2024-05-26
FTX
C++

 这里我们介绍一下 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;
}

能认认真真看到这里相信你一定比我强!!!



下一篇 计算机网络

Comments

Content