首页 > 编程语言 >C++STL 学习笔记

C++STL 学习笔记

时间:2023-08-08 17:34:22浏览次数:44  
标签:容器 迭代 STL 元素 list 笔记 队列 vector C++

C++STL 学习笔记

STL补充

List 链表

  • list<int> mylist = { }链表定义和初始化

  • void push_front(const T & val) 将 val 插入链表最前面

  • void pop_front() 删除链表最前面的元素

  • list.push_back() 增加一个新的元素在 list 的尾端

  • list.pop_back() 删除 list 的最末个元素

  • void sort() 将链表从小到大排序

  • reverse()反转链表

  • list.empty() 若list内部为空,则回传true值

  • list.size() 回传list内实际的元素个数

  • list.front() 存取第一个元素

  • list.back() 存取最末个元素

  • mylist.begin() 首位迭代器

  • mylist.end()末位迭代器

  • 常见for循环

    • for (auto it = mylist.begin(); it != mylist.end(); ++it)

      cout << *it << " ";

    • it是迭代器指针,不能赋值,不能运算(+=不行),只能++

    • list的迭代器只支持双向访问,不支持随机访问,因此不能直接进行加减操作 (和vector等区别)

  • advance(it, n); 将迭代器it向前移动n个位置

  • mylist.insert(it, k); 向第it位迭代器位置插入新元素k(it之前)

  • mylist.erase(it); 删除第it位迭代器位置所指元素

  • mylist.erase(it, it + n); 删除第it位到第it+n位元素(一共删除从it开始到it+n的n个元素)

  • next(it,n)函数是C++ STL中的一个函数,它的作用是返回一个新的迭代器,该迭代器指向原始迭代器向前或向后移动指定距离后的位置 ,被用来移动it迭代器到下n位

vector 存放任意类型的动态数组

  • vector<T>(nSize,t)创建一个vector,元素个数为nSize,且值均为t
  • vector.push_back(k) 在vector尾部插入元素k
  • vector.insert(vector.begin() + 1, 2) 在vector的第2个位置插入一个元素2
  • vector.pop_back() 删除vector尾部的一个元素
  • vector.erase(v.begin() + 1) 删除vector的第2个元素
  • erase()方法接受两个迭代器参数,表示要删除的区间的起始位置和结束位置。被删除的区间包括起始位置的元素,但不包括结束位置的元素。
  • vector.[0]; 访问vector的第1个元素 , 可进行赋值等操作
  • vector.at(0); /访问vector的第1个元素,如果越界会抛出异常
  • for (int i = 0; i < v.size(); i++) { cout << v[i] << " "; } 遍历vector
  • vector.resize() 改变实际元素的个数,新添加的元素会被默认初始化
  • vector.size() 获取vector的大小 ,这是当前存储的元素数量
  • vector.capacity()返回当前容量,这是目前容器最多储存的元素数量
  • vector.front() 返回第一个元素的引用
  • vector.back()返回最后一个元素的引用
  • vector.begin()返回指向容器中第一个元素的迭代器
  • vector.end()返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用
  • vector.empty()判断一个vector是否为空

STL容器适配器

stack

  • stack<T> 创建栈对象
  • push(element):将元素压入栈顶
  • pop():弹出栈顶元素
  • top():返回栈顶元素
  • empty():返回栈是否为空
  • size():返回栈中元素的数量

清空栈操作: while (!myStack.empty()) { myStack.pop(); }

queue

  • queue <int> 创建queue对象
  • push(element):将元素添加到队列的末尾
  • pop():从队列的头部取出元素,并将其从队列中删除
  • front():返回队列头部的元素,但不将其从队列中删除
  • back():返回队列末尾的元素,但不将其从队列中删除
  • size():返回队列中元素的数量
  • empty():判断队列是否为空

priority_queue

  • push(element):将元素添加到优先队列中,根据优先级顺序排列。

  • pop():从优先队列中取出优先级最高的元素,并将其从队列中删除。

  • top():返回优先队列中优先级最高的元素,但不将其从队列中删除。

  • size():返回优先队列中元素的数量。

  • empty():判断优先队列是否为空

  • priority_queue<int, std::vector<int>, std::less<int>> myMaxHeap;创建大顶堆

  • less<int>priority_queue的默认比较函数,因此在创建大顶堆时可以省略第三个参数。以下是更简洁的表达式:priority_queue<int> myMaxHeap;

  • priority_queue<int, vector<int>, greater<int>> myMinHeap; 创建小顶堆

priority_queue<int, vector<int>,greater<int>> 指定了使用greater<int> 作为比较函数,因此创建的优先队列是升序的,即优先级数值小的元素排在队列前面。如果想要创建降序的优先队列,可以使用 less<int> 作为比较函数,例如 priority_queue<int, vector<int>, less<int>>

EG: 优先队列实现滑动窗口求最大值

int main() {
    int k; // 滑动窗口大小
    int n;
    cin >> n >> k;
    vector<int> nums(n); // 输入数组
    priority_queue<pair<int, int>> pq; // 定义优先队列,存放数值和下标

    for (int i = 0; i < nums.size(); i++)
        cin >> nums[i];

    // 先将前 k 个元素加入优先队列
    for (int i = 0; i < k; i++) {
        pq.push({ nums[i], i });
    }

    // 输出第一个滑动窗口的最大值
    cout << pq.top().first << " ";

    // 滑动窗口向右移动,每次加入一个新元素,弹出一个旧元素
    for (int i = k; i < nums.size(); i++) {
        pq.push({ nums[i], i }); // 加入新元素
        while (pq.top().second <= i - k) { // 弹出旧元素
            pq.pop();
        }
        cout << pq.top().first << " "; // 输出当前滑动窗口的最大值
    }

    return 0;
}

deque

  • push_back(element):在队尾插入一个元素。
  • pop_back():删除队尾元素。
  • push_front(element):在队头插入一个元素。
  • pop_front():删除队头元素。
  • front():返回队头元素,但不删除。
  • back():返回队尾元素,但不删除。
  • empty():如果队列为空,返回true,否则返回false。
  • size():返回队列中元素的个数。

heap

  • make_heap(first, last):将[first, last)区间内的元素转换为堆。
  • push_heap(first, last):将[first, last-1)区间内的元素插入堆中。
  • pop_heap(first, last):将堆顶元素移动到[last-1]位置,并重新构建堆。
  • sort_heap(first, last):将[first, last)区间内的元素排序,使其满足堆的性质。
  • is_heap(first, last):如果[first, last)区间内的元素满足堆的性质,返回true,否则返回false。
  • push():将元素添加到堆中。
  • pop():从堆中移除根节点元素。
  • top():返回堆中的根节点元素。
  • empty():检查堆是否为空。
  • size():返回堆中元素的数量。

STL中,堆是通过vector容器实现的,因此要声明一个堆对象,需要先声明一个vector容器,然后使用make_heap()函数将其转换为堆

不如手搓

pair

template<class T1, class T2> struct pair;其中,T1T2表示两个不同的类型。std::pair类包含了两个公有成员变量firstsecond,分别表示这两个值。可以通过以下方式创建和访问std::pair对象:

编译器并不会对std::vector<std::pair<int, int>>中的元素顺序进行任何假设或者判断。它只会根据你的代码中对这个std::vector对象的使用来确定元素顺序。

例如,如果你在代码中使用v[i].first来访问第i个元素的第一个元素,编译器就会认为第一个元素表示数值,第二个元素表示下标。如果你使用v[i].second来访问第i个元素的第二个元素,编译器就会认为第一个元素表示下标,第二个元素表示数值。

迭代器类型补充

在C++中,STL容器的迭代器可以分为5种类型,分别是:

  1. 输入迭代器(Input Iterator):只读,只能单向移动,每个元素只能被访问一次。例如istream_iterator
  2. 输出迭代器(Output Iterator):只写,只能单向移动,每个元素只能被赋值一次。例如ostream_iterator
  3. 前向迭代器(Forward Iterator):可读写,只能单向移动,每个元素可以被访问或赋值多次。例如forward_list
  4. 双向迭代器(Bidirectional Iterator):可读写,可以双向移动,每个元素可以被访问或赋值多次。例如list
  5. 随机访问迭代器(Random Access Iterator):可读写,可以随机访问,支持加减运算,可以跳跃式访问容器中的元素。例如vectordeque

因此,可以根据迭代器的类型来判断容器是否支持随机访问。以下是一些常见的STL容器及其迭代器类型:

  1. vector:支持随机访问迭代器。
  2. deque:支持随机访问迭代器。
  3. list:支持双向迭代器。
  4. forward_list:支持前向迭代器。
  5. set:支持双向迭代器。
  6. map:支持双向迭代器。
  7. unordered_set:支持前向迭代器。
  8. unordered_map:支持前向迭代器。

迭代器类型的不同,使得for循环的操作写法不同

支持随机访问的可以使用熟悉的写法,对元素进行操作;不支持的如双向迭代器要对迭代器进行操作

需要注意的是,对于容器的不同操作,可能需要不同类型的迭代器。例如,对于list容器,如果需要在容器中间插入或删除元素,需要使用双向迭代器;而如果只是进行遍历,可以使用前向迭代器。

而且,要注意的是

stack是STL中的一个容器适配器,它并不是一个容器,因此没有迭代器。stack只提供了很少的操作,主要包括push()pop()top()empty()size()等方法,这些方法都是直接对栈顶元素进行操作,不需要使用迭代器来遍历栈中的元素。因此,stack并不属于任何一种迭代器类型。

STL对于空间大小的规定

STL(标准模板库)中的容器分为两类:

  1. 顺序容器(Sequence Containers):这些容器按照元素在容器中的位置来组织和存储元素。顺序容器包括vectordequelistforward_listarray
    • vectordequearray需要在创建容器对象时指定容器的大小,因为它们使用连续的内存存储元素,所以需要预先分配足够的内存空间。
    • listforward_list不需要指定容器大小,它们使用链表存储元素,可以动态地分配和释放内存。
  2. 关联容器(Associative Containers):这些容器按照元素的键值来组织和存储元素。关联容器包括setmultisetmapmultimap
    • 关联容器不需要在创建容器对象时指定容器的大小,它们使用树形结构存储元素,可以动态地分配和释放内存。

此外,还有另一种容器叫做stackqueue,它们是容器适配器(Container Adaptors),是在顺序容器的基础上提供了特定的接口,使其按照一定的规则进行操作。stackqueue都是基于顺序容器实现的,但是它们不需要指定容器的大小,因为它们使用的是顺序容器的默认构造函数,自动创建一个空的容器对象。

总之,顺序容器中的vectordequearray需要指定容器大小,而listforward_list不需要。关联容器和容器适配器都不需要指定容器大小。

标签:容器,迭代,STL,元素,list,笔记,队列,vector,C++
From: https://www.cnblogs.com/imarch22/p/17614951.html

相关文章

  • 【学习笔记】【数学】计算几何基础
    点击查看目录目录前置知识:叉积与跨立实验前置知识:建议虽然是简单的前置知识,还是打开略过一遍。浮点数与误差分析(少用除法)向量相关向量向量,就是带有方向和大小两个属性的边,通常形式为\(\overrightarrow{AB}=(a_1,a_2)=A\)。运算与性质:判等:两点坐标重合。ilint......
  • C语言听课笔记
    %1f——double;%c——char;%p——&a;%s——char[]求两个数的较大值#include<stdio.h>int main(){ int num1=10; int num2=20; if (num1>num2)    printf("较大值是:%d\n",num1); else    printf("较大值是:%d\n",num2); return 0;}#include<stdio.h&......
  • PyTorch基础知识-新手笔记
    使用NumPy实现机器学习任务使用最原始的的NumPy实现一个有关回归的机器学习任务,不使用PyTorch中的包或类。代码可能会多一点,但每一步都是透明的,有利于理解每一步的工作原理。主要步骤如下:1)首先,给出一个数组x,然后基于表达式y=3x^2+2,加上一些噪声数据到达另一组数据。2)然后,构建......
  • 线段树合并学习笔记
    基本思路线段树合并其实就是简单的暴力合并就可以了。一般是运用于权值线段树。通常是在每个节点都需要要一颗线段树才能维护答案,且有多个节点时,会使用线段树合并。但每个节点所有的权值不能太多,如果都是比较满的二叉树的话,时间复杂度就会很高。通常,加入值的数量跟节点数量在同......
  • STC15 外部中断编程笔记
    以STC15W4K58S4为例,可以将片上的外部中断资源分为“高级”和“低级”两类,EXINT0和EXINT1属于高级的,EXINT2~EXINT4属于低级的。“高级”的外部中断可以配置中断优先级,选择中断源;低级的则不行。EXINT0和EXINT1的配置这两个外部中断的配置寄存器都可位寻址,因此可以直......
  • 复习笔记|《计算机组成原理》
    参考教材:《计算机组成原理》蒋本珊➢前2类题看书中和课件中的有关概念。➢第3、4、5类题请注意平时的作业。如:❑扩展操作码设计❑有效地址的计算❑定点数乘、除运算❑存储器设计❑Cache计算❑微指令操作控制字段的设计第一章➢存储程序概念计算机硬件的组成,存储器控......
  • [学习笔记] Switch语句使用“===”进行比较
    JS中,switch语句会使用恒等计算符(===)进行比较。如上所述,下列代码中因为x定义为字符串10,而case为数字10,因此将不会弹出“HelloWorld”:var x="10";switch(x){    case 10:alert("Hello");}实际应用时应注意这点。......
  • 【刷题笔记】9. Palindrome Number
    题目Determinewhetheranintegerisapalindrome.Aninteger is a palindromewhenit readsthesamebackwardasforward.Example1:Input:121Output:trueExample2:Input:-121Output:falseExplanation:Fromlefttoright,itreads-121.Fromrightto......
  • 《从0到1:JavaScript快速上手》笔记(一)
    一、两个十分有用的方法document.write():表示在页面输出一个内容alert():表示弹出一个对话框二、变量与常量在JavaScript中,变量指的是一个可以改变的量,也就是说,变量的值在程序运行过程中是可以改变的。(1)在JavaScript中,给一个变量命名,我们需要遵循以下2个方面的原则。变量有字母、......
  • RotatE 学习笔记
    目录RotatEWhatisRotatE?MotivationModelNegativesamplingLossfunctionExperimentsOthersSummaryRotatEpaper:RotatE:KnowledgeGraphEmbeddingbyRelationalRotationinComplexSpaceWhatisRotatE?本文是北大和加拿大的研究团队发表在ICLR2019上的文章,提出了......