常用 STL 整理

常用 STL 整理

vector

可变长数组,变长是基于 倍增 的思想

系统为某一个程序分配空间时,有一个特点,

他所需的时间基本上与空间大小无关,只与申请次数有关

(即 100 和 1000 没区别,只和请求次数有关)

因此,vector的优化目标是,减少申请的次数(优化时间,可以浪费空间)

起初先申请一个 小的空间(例如32),当我们插入到边界的时候,就会申请到 64个空间

然后把 原来的32个元素copy过来,(每一次数组长度不够的时候,就把数组的长度*2,再把原来的

元素copy过来。

假设要申请 n 的数组,起初为 1 ,我们一共会copy 1 + 2 + 4 + 8....+5*10^5 == 10^6 ,

因此大概copy的操作是 10^6 ,均摊下来, 尾部插入的操作就是(O(1)) 的,随机插入是(O(n))

初始化
vector<typename> name;
vector<int> a(n); // 初始化大小为n的数组,0~n-1
vector<int> a(n,3); //初始化大小为n的数组,所有值均为3
vector<vector<int> > name; // 定义二维的vector,两维都能动态变长
vecotr<int> a[n]; // 第一维已经固定,第二维才是vector
访问

(1) 通过下标随机访问 范围是 0 ~ size() - 1

(2) 通过迭代器访问 iterator (类似于指针)

vector<int>::iterator it;
通过 *it 来访问元素//支持++,--
  • 其中 v[i] 和 *(v.begin() + i) 是等价的
常用函数
push_back(); // 尾端插入 O(1)
pop_back(); // 尾端删除 O(1)
size(); // 返回元素个数 O(1) ,返回的是 unsigned 类型
clear(); // 虚假的清空 不能真正的清空元素个数,放弃使用,直接新定义一个重名的,当做清空
v = vector<int>(); // 真正的清空 
insert(it,x); // 在迭代器 it 处,插入一个元素 x, O(n)
erase();// 删除单个元素 O(n)
erase(v.begin(),v.end());// 删除区间的元素 O(n)
// 支持比较运算,按字典序来比较

pair

可以看作一个内部有两个元素的结构体,元素类型任意指定

初始化
pair<typename1,typename2> p;// typename 可以为任意类型
pair<int,pair<int,int> > p; // pair支持多重嵌套
//临时构造pair
p = make_pair("123",123);
p = {"123",123}; // C++ 11 写法
访问
p.first; // 第一个关键字
p.second; // 第二关键字
用途

1.支持比较运算,排序的时候,以first为第一关键字,second为第二关键字

2.用来代替二元结构体及其构造函数

3.作为map的键值对来进行插入

string

C++ 封装好的字符串

初始化
string s = "123";
访问
c_str() 可以返回 string 类型的字符串存储的起始地址
通过迭代器访问 string::iterator it;
s[i]; // 像数组一样访问
常用函数
size() 与 length() 基本相同,O(1);
支持字典序比较 <=,<,>=,>....
insert(pos,string);// 在pos位置,插入string字符串  O(n)
erase();// O(n)
substr(pos,len); // 返回从 pos 开始,长度为 len 的字符串 O(len)
str1.find(str2); // 返回str2 在 str1 中第一次出现的位置,如果没有出现,返回 npos O(n^2)
string::npos;// 是一个常数 -1
replace(); // 区间替换字符串
+ // 拼接

queue

queue , push(),pop(),front()

push() 队尾插入

front() 返回队头元素

back() 返回队尾

pop() 弹出队头

没有clear() 操作

清空的时候,直接重新构造就行了 q = queue();

priority_queue

// 优先队列,堆,默认是大根堆

小根堆的时候,直接插入负数,就可以变成小根堆 (黑科技

直接定义成小根堆

priority_queue<int,vector,greater> heap;

stack

// 栈

O1

deque

// 双端队列,随机访问

加强版的 vector,有clear,支持随机寻址,速度很慢(一般不用,太慢了

front()

back()

push_back()

push_front()

pop_back(),pop_front()

set , multiset(可以插入重复元素),

log n

不能插入重复元素(插入的话,会被忽略掉

insert()

find() // 如果不存在,返回end的迭代器

count() 返回某一个数的个数

erase()

​ (1) ,输入一个数x,删除所有的 x O(k + logn)

​ (2),输入一个迭代器

lower_bound() 返回大于等于 x 的最小的数

upper_bound() 返回 大于 x 的最小的数

不存在的话,返回end()

map,multimap

// 平衡树,基于平衡二叉树(红黑树 (平衡二叉树的一种)),hash

动态维护一个有序序列

全是log n,包括 ++,--

insert(x) 插入的数,是一个pair

erase() 输入的参数,是pair或者迭代器

find()

[] //像数组一样,用map,时间复杂度是 O(log n)

lower_bound,upper_bound

unordered_set,unodered_map,unordered_multiset,unordered_multimap // 基于hash表

和上面都是类似的,绝大多数操作都是 O(1) 的,都是无序的,

不支持 upper_bound,lower_bound

bitset// 压位,

例如 1024 bool 字节 需要 1024B = 1kb

比正常的 bool 数组省 8 位内存,

bitset利用了每一 个 bit

bitset<1000> s;

count() 返回有多少个 1

any() 返回是否至少有一个 1

none() 是否全为空

set() 把所有 位 置为 1

set(k,v) 将第k位,变成 v

reset() 把所有位 变成 0

flip() 等价于 ~

flip(k) 是把 第 k 位取反

list // 链表,用的不多

参考

https://zh.cppreference.com/

《算法笔记》

《算法竞赛入门经典》

《算法竞赛进阶指南》

原文地址:https://www.cnblogs.com/lukelmouse/p/11743183.html