STL库总结

本文详细介绍了STL中的重要容器:set的插入、查找、删除操作;vector的动态数组特性及常用函数;map的键值对存储及其操作;bitset的位运算和功能;以及queue的基本使用。这些内容对于理解和应用STL库至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个东西还蛮重要的。。。就是在考场上正解想不出来,打暴力需要用一些工具这时又发现忘了怎么用了,这就很尴尬了。。。

1.set

实用性很高,所以放最前面啦~

set 内部通常采用红黑树实现。平衡二叉树的特性使得 set 非常适合处理需要同时兼顾查找、插入与删除的情况。 ——摘自OI wiki

set 中的元素默认从小到大自动排序,但比起堆来支持的操作更多。 其中 multiset 支持插入重复数字,而 set 不能,除此以外操作基本相同。

指针

定义是这样式儿的:

set<int>::iterator it1;
multiset<int>::iterator it2;
set<pair<int,int> >::iterator it3;

支持 * 解除引用(就是将指针变为指针指向的东西)

it=s.lower_bound(val);
int x=*it;

set 的迭代器为双向访问迭代器 ,指针仅可以左移或右移(也就是 ++ 或 --),会移到从小到大排序该数的上/下一个,时间复杂度 。

it=--s.lower_bound(val);

函数

begin()/end()

begin() 返回首元素的迭代器,也就是指向首元素的指针,s.begin() 就是集合中最小的一个。

但由于 set 是左闭右开的,end() 返回的便是尾元素再向后一位的位置,或者说集合中最大元素的下一个位置的迭代器(引自算阶),也就是说是没有元素的,使用要注意。

rbegin() 与 rend() 是指向逆向数组的迭代器,通俗讲 rbegin()  end()rend()  begin()然并卵

函数名前加 c 为只读迭代器,通常情况下是等义的,例如 begin()  cbegin()end()  cend(),但不能通过只读迭代器修改集合中的值(引自OI wiki)。

所以基本上会用begin()与end()就行 时间复杂度 。

insert()

插入操作。当使用 set 时如果插入的是重复数字,那么什么也不会发生,所以说有可重复的数字就要用 multiset。时间复杂度 。

find()

在集合中查找等于  的元素,并返回指向该元素的迭代器。若不存在,则返回 s.end()引自算阶)。时间复杂度 。

erase()

可以调用指针,删去当前指针所引向元素,这样会删去一个元素。通常 s.erase(s.find(x)) 配合食用。时间复杂度 。

也可以调用元素,删去这个值,这样会删去所有等于该元素的值,返回删除元素的个数。时间复杂度 ,其中  为被删除的元素个数。

还可以区间操作。erase(s,t) 删除迭代器在  范围内的所用元素(引自OI wiki)。

lower_bound()/upper_bound()

与平常用的一样,但只需要调用查找的关键值就行。函数返回值是迭代器,如果不存在,返回 s.end()。时间复杂度 。

其他函数

size() 返回集合内元素个数。

empty() 返回集合是否为空,空返回,否则返回。

clear() 为清空操作。

count(x) 返回集合中的个数。

其他

自定义比较方式

特殊情况下用到。

struct cmp {
  bool operator()(int a, int b) { return a > b; }
};

set<int, cmp> s;

(引自OI wiki) 这样就能实现从大到小排序了~

2.vector

vector 是 STL 提供的内存连续的、可变长度的数组(亦称列表)数据结构。能够提供线性复杂度的插入和删除,以及常数复杂度的随机访问。 ——摘自OI wiki

我们一般使用 vector 是因为它可以动态分配内存,空间有多大开多大,就可以在每个储存长度未知但总长度已知的情况下使用了。它也能支持很多操作。

指针

定义是这样式儿的:

vector<int>::iterator it

支持 * 解除引用。

vector 的指针能提供的骚操作更多,例如与一个整数相加减:

for(int i=1;i<=10;i++) v.push_back(i);
it=v.begin();
it+=2;
cout<<*it;

结果输出3。

把 vector 的两个指针(迭代器)相减,得到两个迭代器对应下标之间的距离:

for(int i=1;i<=10;i++) v.push_back(i);
it1=v.begin(),it2=--v.end();
cout<<it2-it1;

结果输出9。

函数

这里一些函数与 set 一样就不提啦。

front()/back()

front() 返回 vector 中的第一个元素,back() 返回最后一个元素。

push_back/pop_back()

在末尾插入/删除元素,时间复杂度为线性。

其他

放几个可能用的到的。

访问

at(pos) 返回容器中下标为 pos 的引用。如果数组越界抛出 std::out_of_range 类型的异常。

与直接数组访问同理,但不执行越界检查。

data() 返回指向数组第一个元素的指针。(引自OI wiki)。

长度

resize() 改变 vector 的长度,多退少补。改变之后就跟普通数组一样了。

v.resize(len);

max_size() 返回容器的最大可能长度。

cout<<v.max_size();

输出很怪的值:4611686018427387903。

3.map

map 是有序键值对容器,它的元素的键是唯一的。搜索、移除和插入操作拥有对数复杂度。map 通常实现为红黑树。 ——摘自OI wiki

就是哈希啦~ 懒得手写哈希可以用这个。

定义方式:

map<key_type,value_type> m;//key 和 value 可以是任意类型。
map<int,int> m;
map<pair(int,int),vector<int> > m1;

引自算阶) map 的指针与 set 的指针类型是一样的,解除引用后,将得到一个二元组 pair<key_type,value_type>

函数

insert()/erase()

元素的插入/删除。insert() 的参数是 pair<key_type,value_type>erase() 的参数可以是 key 或者是迭代器(引自算阶)。

 操作符

map 支持像数组那样的访问、查找。但如果查找的值不存在则会新建一个空的二元组,因此要配合 find() /count() 使用。

map 还有其他函数,但不常用就不说了。

其他

unordered_map

无序关联式容器则采用哈希方式存储元素,内部元素不以任何特定顺序进行排序,所以访问无序关联式容器中的元素时,访问顺序也没有任何保证。 ——摘自OI wiki

因为没有排序,unordered_map 通常会比 map 快一些。但在特殊情况下会被卡,需要酌情使用。

4.bitset

一些卡内存的题可能用到。能够用很小的空间储存  串(每  位占一个字节),且支持操作多,十分方便。

bitset 的复杂度一般被认为是 ,其中 (计算机的位数)(引自OI wiki)。

话说 bitset 严格来讲并不属于 STL (大惊

定义方式:

bitset<4000> bit

其中  是 bitset 的位数。

位运算

~bit 按位取反。

& | ^ 与、或、异或。

<< >> 左移右移。

支持数组下标读取方式。(下标从  开始)

s=13;
cout<<s<<endl;
s=~s;
cout<<s<<endl;
s>>=1;
cout<<s<<endl;
s^=1;
cout<<s<<endl;
cout<<s[3];

输出: 01101 10010 01001 01000 1

函数

count() 返回  的个数。

any() : 若存在某一位是  则返回 ,否则返回 。

none() : 若所有位都是  则返回 ,否则返回 。

set() 把所有位变为 。set(,) 把第  位改为 。

reset() 把所有位变为 。reset() 把第  位变为 。

flip() 把所有位取反,flip()同理(引自OI wiki 与 算阶)。

其他函数不常见就不写了~

5.queue

这个用法更简单了~ 来写一下 priority_queue 的用法。

用堆也可以实现很多操作,常用的如对顶堆。

priority_queue<int> q1//大根堆
priority_queue<int,vector<int>,greater<int> >q2//小根堆

小根堆也可以用重载小于号来实现。

更方便的用法是当成负数存进去~

如果是套 pair 的话会按第一位优先排序。

deque 是双端队列,支持头与尾的插入、弹出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值