STL的函数

序列式容器:

• 向量(vector):尾部可高效增加元素的顺序表。
• 数组(array):定长的顺序表,C 风格数组的简单包装。(C++11 标准)
• 双端队列(deque):首尾都可高效增加元素的顺序表。
• 列表(list):可以沿双向遍历的链表。
• 单向列表(forward_list):只能沿一个方向遍历的链表。

有序关联式容器:

• 集合(set):有序地存储互异元素的容器。
• 多重集合(multiset):元素可以相等的 set。 • 映射(map)由(键,值)对(二元组)组成的容器,要求键互异,按键有序存储。
• 多重映射(multimap):键可以相等的 map。

无关联式容器:

unordered_set/unordered_multiset
unordered_map/unordered_multimap,元素乱序,用于判断 元素是否存在。使用哈希实现。(C++11 标准)

容器适配器:

容器适配器并不是容器,它们不具有容器的部分特点。
• 栈(stack)后进先出的容器,默认是对双端队列(deque)的包装。
• 队列(queue)先进先出的容器,默认是对双端队列(deque)的包装。
• 优先队列(priority_queue):元素的有序的一种队列,默认是 对向量(vector)的包装。

容器声明:

containerName <typeName> name

迭代器:

在 STL 中,迭代器用来访问和检查 STL 容器中元素的对象,它的行为模式和指针类似。
迭代器可以看作一个数据指针,主要支持两个运算符:自增(++) 和解引用(*),其中自增用来移动迭代器,解引用可以获取或修改它指向的元素。
指向某个 STL 容器 container 中元素的迭代器的类型一般为container::iterator。 在 C++11 后,可使用 auto it=a.begin(); 的方式自动识别迭代器类型。

容器共有成员函数:

• =:赋值。
• begin():返回指向开头元素的迭代器。
•end():返回指向末尾的下一个元素的迭代器。‘end()‘ 不指向某个元素,但它是末尾元素的后继。
• size():返回容器内的元素个数。
• empty():返回容器是否为空。
• swap():交换两个容器。---->交换地址
• clear():清空容器。

vector:

• 基于字典序重载了比较运算符。
• 支持列表初始化。和随机访问(使用类似数组的方式进行下标访问)
•  v.resize(x,y) 将 v 的大小重设为 x,若原本大小不足 x,则用 y 填充。y 可不写,默认为 0。

• vector<int> v(x,y) 创建一个初始大小为 x 的 vector,并用 y填充。y 可不写,默认为 0。

• v.front() v 的首元素。
• v.back() v 的尾元素。
• v.rbegin() 指向 v 逆向的首元素的迭代器。
• v.rend() 指向 v 逆向的尾元素后继的迭代器。
• v.push_back(x) 在 v 的末尾加入 x。 • v.pop_back() 删除 v 的末尾元素。
• swap(v1,v2) 交换 v1,v2。

deque:

双端队列。
与 vector 几乎一致(底层实现不一致)。
多的函数:
• q.push_front(x) :在 q 的队首插入一 x。

• q.pop_front(): 删除 q 的队首元素。

list:

双向链表。
使用与 deque 基本一致。
元素访问不一致:
不能随机访问,要从头或尾迭代器开始。
• l.front() 返回首元素的引用。
• l.back() 返回末尾元素的引用。

set:

set 底层逻辑为红黑树(是一种平衡二叉搜索树)。set 默认升序。不支持随机访问

set<int> q;     //以int型为例 默认按键值升序
set<int,greater<int>> p;  //降序排列 
int x;
q.insert(x);	//将x插入q中
q.erase(x);		//删除q中的x元素,返回0或1,0表示set中不存在x
q.erase(it);    //将 s 的迭代器 it 指向的元素删除,要求 it 必须合法。
q.erase(begin,end);//将 s 中迭代器 [begin,end) 之间的元素删除。
q.clear();		//清空q
q.count(x);     //返回 s 中 x 的个数。(返回1或0)
q.empty();		//判断q是否为空,若是返回1,否则返回0
q.size();		//返回q中元素的个数
q.find(x);		//在q中查找x,返回x的迭代器,若x不存在,则返回指向q尾部的迭代器即 q.end()
q.lower_bound(x); //返回一个迭代器,指向第一个键值不小于x的元素,若不存在则返回 s.end()。
q.upper_bound(x); //返回一个迭代器,指向第一个键值大于x的元素,若不存在则返回 s.end()。

q.rend();		  //返回第一个元素的的前一个元素迭代器
q.begin();		  //返回指向q中第一个元素的迭代器

q.end();		 //返回指向q最后一个元素下一个位置的迭代器
q.rbegin();		 //返回最后一个元素

set的注意点:

• set 迭代器的 ++/– 时间复杂度为均摊 O(1),最坏 O(log n)。遍历一个 set 的时间复杂度为 O(n),而不是 O(n log n)

• 使用 algorithm 库的 lower_bound/upper_bound 对 set 的时间复杂度为 O(n)。

• 使用 algorithm 库的 nth_element 对 set 的时间复杂度为O(n)

set多元素应用(结构体)

#include<iostream>
#include<set>
using namespace std;
struct node{
	int a,b;
	bool operator< (const node W)const
	{
		return a>W.a;  //按a的值升序 
	}
}t;
int main()
{
	set<node> q;
	t.a=1;
	t.b=2;
	q.insert(t);
	
	t.a=4;
	t.b=2;
	q.insert(t);
	
	t.a=3;
	t.b=5;
	q.insert(t);	
	
	set<node>::iterator i;
	for(i=q.begin();i!=q.end();i++)
	{
		t=*i;
		cout<<t.a<<" "<<t.b<<endl;
	}
	return 0; 
}

mutiset:

可重集。允许有相同元素的 set。 与 set 完全一致。
注意: 因为允许相同元素,所以 count 的时间复杂度最坏会是 O(n) 的。

map

映射。
键和值之间一一对应且保证键升序,不能存在多个相同键。
若在 map 中插入多个相同键值对,保留第一个。
常常应用在 string 和 int 的映射上,例如学生成绩的查询;或是统计值较大的数字个数。
操作与 set 一致,替换成对 map 键的操作。
特别地:可以使用 mp[key] 的方式访问键对应的值。使用mp[key] 时,若 mp 中没有键为 key 的元素则会自动加入一个,对应的值默认为 0。所以不建议使用 mp[key] 判断是否存在,而应使用 mp.find(key)-->(使用方法和set的一致)。

multimap

键可以重复的 map。
操作与 map 一致。
特别地:但因为键可以重复,所以 multimap 没有通过键访问值的方法

unordered

方法与有序关联式容器一致。
除了没有与“有序”有关的方法,例如:lower_bound 和upper_bound。
由于是基于哈希实现的,一般情况下时间复杂度为 O(1)。但在默认情况下,可以被构造数据卡时间复杂度,将 O(1)的时间复杂度卡成 O(n)。但可以通过自定义哈希函数,在一定程度上防止被卡。

stack

栈。
是一种后进先出的容器适配器,仅支持查询或删除最后一个加入的元素,不支持随机访问,不支持迭代器。
• q.top() :访问栈顶元素。
• q.push(x) :将 x 插入栈顶。
• q.pop() :删除栈顶元素(栈不能为空)。
• q.size() :查询栈内元素数量。
• q.empty(): 查询栈是否为空。

queue

队列。
是一种先进先出的容器适配器,仅支持查询或删除第一个加入的元素,不支持随机访问,不支持迭代器。
• q.front() :访问队首元素。

• q.push(x) :向队列中插入 x。

• q.pop() 删除队首元素(队列不能为空)。

• q.size() :查询队列内元素数量。

• q.empty() :查询队列是否为空。


priority_queue

  • top 访问队头元素
  • empty 队列是否为空
  • size 返回队列内元素个数
  • push 插入元素到队尾 (并排序)
  • emplace 原地构造一个元素并插入队列
  • pop 弹出队头元素
  • swap 交换内容


string

字符串。
string 可以动态分配内存,不用初始设定。支持 cin/cout 进行输入输出。
string 重载了加法运算符,使用 + 可以简单拼接两个字符串。
注意:

• a = a + b,时间复杂度为 O(|a + b|)。

• a+ = b,时间复杂度为 O(|b|)。
string 基于字典序重载了比较运算符。

• s.length() :查询 s 的长度,返回和 s.size() 相同。
• s.size() :查询 s 的大小,返回和 s.length() 相同。
• s.find(str,pos) :从 pos 起查询 s 中第一次出现 str 的位置,如果没有出现返回 -1。pos 可不传参,默认从 0 开始。
•s.substr(pos,len) :在 s 中从 pos 起截取最多 len 个字符组成字符串。
• s.insert(pos,cnt,str) :在 s 中从 pos 起插入 cnt 个 str 字符串。cnt 可不传参,默认为 1。 •s.erase(pos,len) :在 s 中从 pos 起删除 len 个字符。len 可不传参,默认删除 pos 起的全部字符。
• s.replace(pos,len,str) :将在 s 中从 pos 起 len 个字符替换成str 字符串。
• s.replace(first,last,str): 将在 s 中 [first,last) 之间的字符串替换成 str。
注意:

• s.length()/s.size() 返回值均为 unsigned。若是在 s.size()-1时,s.size()=0,则是未定义行为(不同编译器返回结果不同),一般认为会变成极大的正数。
• C 语言中对字符串长度的处理函数 strlen() 的时间复杂度关于字符串长度呈线性。而 s.length() 和 s.size() 均为 O(1)。

bitset

bitset 是 C++ 标准库中的一个存储 0/1 的大小不可变容器。严格来说,bitset 并不属于 STL。

由于内存地址是按 byte 寻址,而非 bit。一个 bool 类型的变量,虽然只存储 0/1 但也占 1 byte 的内存。而 bitset 使得一个 byte 存储 8 位 0/1。                    

bool a[10000];//10000*1 byte
bitset <10000> b;//10000*1 bit

定义:

bitset <N> name; // 定义长度为 N 的二进制数组,命名为 name;
bitset <N> name(num);// 定义长度为 N 的二进制数组,命名为 name,将数字 num 的二进制存到其中;
bitset <N> name(string); // 定义长度为 N 的二进制数组,命名为 name,将01串 string 存到其中,长度不够前补 0,长度过长截断;
bitset <N> name(char[]); // 定义长度为 N 的二进制数组,命名为 name,将 01字符数组存到其中,长度不够前补0,长度过长截断;

bitset 支持许多独特的运算,由于 bitset 的 0/1 性质,使得其支持位运算。
• [] 访问 bitset 某一位。
• ==/!= 判断两个 bitset 内容是否完全相同。
• &、|、ˆ 、<<、>>,对整个 bitset 进行位运算。
• <> (流运算符,注意与位运算的区分)意味着可以通过cin/cout 进行输入输出类似 string。

b2 |= b3; //两个二进制数取或操作; 
b2 &= b3; //两个二进制数取与操作; 
b2 ^= b3; //取异或;
b2 = ~b2; //取反; 
b2 <<= 2; //左移右移;

成员函数:

• count() :查询 1 的数量。

• size() :查询 bitset 的大小。

• test(x) :查询第 x 位,和 [] 的区别是越界检查,test 越界后会抛出异常。

• any(): 查询是否存在 1。

• none() :查询是否不存在 1。

• all(): 查询是否全是 1。(C++11 标准)

• set(x,y) 将 bitset 第 x 位设置为 y。可以无参数,将整个bitset 设置为 1。                                     

• reset(x) 将 bitset 第 x 位设置为 0。可以无参数,将整个bitset 设置为 0。                                   

• flip(x) 翻转 bitset 第 x 位。可以无参数,默认翻转整个。

• to_string() :返回将 bitset 转换为 string 的结果。

• to_ullong() :返回将 bitset 转换为 unsigned long long 的结果。(C++11 标准)

int cnt_1 = b2.count(); //查询二进制数组中,1的个数;
int len  = b2.size(); //二进制数组的长度,就是定义的长度; 
int test = b2.test(7); //判断第x个位置是0还是1,也就是输出第x个位置,注意逆序;

b2.flip(); //将二进制每一位取反;
b2.flip(3); //将二进制第x位取反;
b2.set(); //将二进制每一位置为1; reset置为0; 
b2.set(3); //将第x个位置置为1;
	
string ss = b2.to_string(); //将二进制数组转化为字符串。 

pair

二元组。
使用:
pair<Typename,Typename> a;
使用 a.first 访问 a 的第一个元素,a.second 访问 a 的第二个元素。
pair 相较于自定义 struct 的优势是自定义了比较运算符,按照先比较第一个元素,再比较第二个元素的原则进行。在部分情形下更加方便。(前提是 pair 内的 Type 存在对应的比较运算符)

tuple

元组(C++11 标准)。
类似于 n 元的 pair,通常可以用 pair 套 pair 的方式做等价实现。
略。

rope

块状链表(采用可持久化平衡树实现)。
rope 不是真正的块状链表,只是起到块状链表的作用,所以其时间复杂度为 O(log n)。

使用:

rope 使用较特殊,需要使用以下代码来引入:

#include<ext/rope>
using namespace __gnu_cxx;

rope<Typename> a;
• a.push_back(x) :在 a 的末尾插入 x。

• a.insert(pos,x): 在 a 中的 pos 位置加入元素 x。

• a.erase(pos,len) :在 a 中的 pos 位置起删除 len 个元素。

• a.at(x) 或 a[x] :查询 a 的第 x 个元素。

• a.length() 或 a.size() :查询 a 的大小。

STL算法:

STL 提供了大约 100 个实现算法的模版函数,基本都包含在 <algorithm> 之中,还有一部分包含在 <numeric> 和<functional> 中。

• find(s.first,s.last,v) :在容器 s 中迭代器 [first,last) 之间查找 v,返回迭代器。若找不到,返回 s.last。(时间复杂度O(n) )

• reverse(s.first,s.last): 翻转容器 s 中迭代器 [first,last) 之间的内容。

• unique(s.first,s.last) :去除容器 s 中迭代器 [first,last) 之间相邻的重复元素。返回 s.last。

•shuffle(s.first,s.last,rng) :随机打乱容器 s 中迭代器 [first,last)之间元素。rng 随机数生成器,一般情况使用以真随机数生成器 random_device 播种的梅森旋转伪随机数生成器mt19937。

•sort(s.first,s.last,compare): 对容器 s 中迭代器 [first,last) 之间的元素排序,compare 为比较函数,可不传参。默认升序。(stable_sort 为稳定排序)

• binary_search(s.first,s.last,v) :在容器 s 中迭代器 [first,last) 范围内二分查找 v。返回 1 表示存在 v,返回 0 表示不存在 v。

• lower_bound(s.first,s.last,v) :返回容器 s 中迭代器 [first,last)范围内找到第一个大于等于/小于等于(取决于范围内元素是升序还是降序,若范围内元素为无序,不会报错,但结果不一定正确)v 的迭代器,找不到返回 s.last。

• upper_bound(s.first,s.last,v): 返回容器 s 中迭代器 [first,last)范围内找到第一个大于/小于(取决于范围内元素是升序还是降序,若范围内元素为无序,不会报错,但结果不一定正确)v 的迭代器,找不到返回 s.last。

• merge(v1.first,v1.last,v2.first,v2.last,back_inserter(v3)) :把容器 v1 中迭代器 [first,last] 范围元素和容器 v2 中迭代器[first,last) 范围内元素有序合并后插入到 v3 后。(要求 v1 v2对应范围内均升序)线性时间复杂度。

• inplace_merge(v.first,v.middle,v.last) :将容器 v 中迭代器[first,middle) 和 [middle,last) 范围内的元素有序合并(要求[first,middle) 和 [middle,last) 均升序)。线性时间复杂度。

• next_permutation(s.first,s.last) :将容器 s 中迭代器 [first,last)范围的排列更改为全排列中的下一个排列。

• prev_premutation(s.first,s.last) :将容器 s 中迭代器 [first,last)范围的排列更改为全排列中的上一个排列。

• partial_sum(v.first,v.last) :求容器 s 中迭代器 [first,last) 范围的前缀和。线性时间复杂度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值