C++ STL学习笔记

本文是关于C++ STL的学习笔记,详细介绍了vector、pair、string、queue、priority_queue、stack、deque、set、map及其变种的使用方法、特性,包括基本操作和时间复杂度分析,强调了vector的动态增长策略和比较运算,以及pair作为数据结构的便捷性。
摘要由CSDN通过智能技术生成

STL是个宝

由于C++ STL的开放,代替了那些需要老老实实写结构体来实现堆栈二叉树等数据结构的C等语言,很多算法不需要自己来实现了

  • vector
  • pair
  • string
  • queue,priority_queue
  • stack
  • deque
  • set,map,multiset,multimap
  • unordered_set,unordered_map,unordered_multiset,unordered_multimap
  • bitset

所有容器都有的两个时间复杂度为O(1)的方法:
a.size() 返回容器中元素的个数
a.empty() 返回容器是否为空

vector不定长数组

vector也叫变长数组,即数组长度可以动态变化。用到了倍增的思想

基本操作:
  1. 初始化vector的方法
vector<int> a(10);		开一个长度为10 的vector数组
vector<int> a(10,3);		把每一个元素初始化为特定的3 
vector<int> a[10];			定义10个vector
vector<int> a;				普通定义法
  1. vector的常用方法
  • clear() 清空方法

  • size() 返回元素个数方法

  • empty() 判断是否为空

  • front()/back() 返回vector 第一个数和最后一个数

  • push_back()/pop_back() 向数组尾插入/删除

  • begin()/end() vector的第0个数/vector的最后一个数的后面一个数
    这个与sort()函数对应,sort函数传入末地址项需要+1才能正常用

  • [ ]读取数组中的某个数,和普通数组一样

  1. tips:C++里有一个特点 ,当操作系统为某一个程序或者进程分配空间的时候,所需的时间基本上和空间大小无关,仅仅与申请次数无关
    举个栗子就是:申请一个长度为1000的数组和1000个长度为1的数组 ,时间上有1000倍的区别。
    所以进行优化时优化的思路是要尽量减少vector申请空间的次数,可以浪费空间

    总结起来:
    vector的倍增思想如下,首先申请32位,当32位不够的时候,新建一个长度大一倍的vector,然后把旧32位copy到新32位上,这样的话就新开了32位出来。
    vector申请数组的思想

vector还支持一个黑科技:比较运算
vector<int> a(4,3),b(3,4);
if(a<b) puts("yes");

输出结果显示a<b

这种比较是按字典序比较的

在数学中,字典或词典顺序(也称为词汇顺序,字典顺序,字母顺序或词典顺序)是基于字母顺序排列的单词按字母顺序排列的方法。 这种泛化主要在于定义有序完全有序集合(通常称为字母表)的元素的序列(通常称为计算机科学中的单词)的总顺序。
对于数字1、2、3…n的排列,不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列 12354和12345,排列12345在前,排列12354在后。按照这样的规定,5个数字的所有的排列中最前面的是12345,最后面的是 54321。

用于存储一个二元组的pair

pair<int,int> 或pair<int, string>等不同或同种类型变量
访问元组中的第一/第二个元素的方法是first()和second()方法

pair的初始化方法
pair<int,string> p;
p = make_pair(10,"abc");
p={20,"abc"}
pair的用处:

假设一个东西有着两种不同的属性,并需要按照某一个数为标准进行排序。
即可把要排序的关键字放到first里面,即可完成排序

pair是支持比较运算的,以first为第一关键字,以second为第二关键字进行比较(也相当于是一种字典序)

pair可以用于存储多元组

多元组存储方法为

pair<int,pair<int,int>> p;
pair相比于结构体

pair已经帮我们实现了一个结构体,且帮我们写好了一个比较函数

string

处理字符串的利器

支持的方法
  1. 字符串加法
string a ="abc";
a+="def";
a+='g';

输出a: abcdefg
  1. substr()方法
substr返回的是一个子串,有两个要传入的参数,第一个参数是起始位置,第二个参数是子串的长度
a.substr(110);
第二个参数可省略,省略的话直接叫后面的字符串输出完
当长度大小到顶了,就输出到最后一位为止
  1. c_str()方法 【 返回字符串的起始地址以便输出
printf("%s",a.c_str());
即可正常输出字符串a
  1. size()方法=length()方法
    返回数组长度

queue 队列

先进先出

常用方法
  1. push() 向队尾插入一个元素
  2. front() 返回队头元素
  3. back() 返回队尾元素
  4. pop() 弹出队头元素
  5. queue是没有clear函数的 要清空一个队列直接重新构造就可以实现了

priority_queue优先队列(堆)

堆是一个二叉树,父节点的值一定比子节点大。所以队头一定是全队里最大的。

定义的堆默认是大根堆,即根节点最大

那么怎么实现小根堆呢?
  1. 方法1
    在插入一个元素的时候,直接插入这个数的负数(小技巧)
  2. 方法2
    在定义堆的时候就把后面两个参数写出来
    priority_queue<int,vector<int>,greater<int>> heap
常用方法
  1. push() 插入一个元素
  2. pop() 弹出栈顶元素
  3. top() 返回栈顶元素(极值)

stack栈

先进后出

常用方法
  1. push() 向栈顶插入一个元素
  2. top() 返回栈顶元素
  3. pop() 弹出栈顶元素

deque双端队列

队头队尾均可插入删除,队内元素可直接访问,相当于加强版的vector

什么操作基本都支持,但是速度很慢,用的话要谨慎

常用方法

size()
empty()
clear()
front()
back()
push_back()/pop_back()
push_front()/pop_front()

set 集合,map 映射,multiset,multimap 平衡树

基于平衡二叉树(红黑树,是平衡二叉树的一种)来实现的,本质上是动态地维护一个有序的序列

介绍及常用方法
set/multiset

所有操作的时间复杂度是O(logn)

set与multiset的区别:set每个元素最多只出现一次,大于一次的操作都会被忽略,但是multiset没有这个限制,每个元素可以出现多次。

  1. insert() 插入一个数

  2. find() 查找一个数

  3. count() 返回某一个数的个数。当然,在set中只可能取0或1。

  4. erase() 两种参数:
    (1)输入的是一个数x,删除所有x
    (2)输入一个迭代器,删除这个迭代器

  5. 核心操作:lower_bound()/upper_bound()
    lower_bound() 返回大于等于x的最小数的迭代器
    upper_bound() 返回大于x的最小数的迭代器

map/multimap

所有操作的时间复杂度是O(logn)

首先说map:

map是从键(key)到值(value)的映射。因为重载了[ ]运算符,map像是更高级版的数组。
例:
用一个map<string,int> month_name来表示“月份名字到月份编号”的映射,然后用month_name[“July”]=7这样的方式来赋值。

multimap:

map 与 multimap是存储key-value(键-值 对)类型的容器。
不同之处在于:map只允许key与 value一一对应;multimap一个key可对应多个value;

对比图
insert() 插入的参数是pair
erase() 输入的参数是pair或者迭代器
lower_bound() 返回大于等于x的最小数的迭代器
upper_bound() 返回大于x的最小数的迭代器
[ ] 与普通数组类似

unordered_set,unordered_map,unordered_multiset,unordered_multimap

C++中已经实现好了的哈希表
它们是基于哈希表实现的

unordered造成的影响是所有基于排序的方法都不能用,但是时间复杂度由O(n)变为O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值