信STL,得永生(STL大法好)

STL大法好!

当然,是不可能得永生的,但它可以延长你的在役时间

最近总结了一些STL的神奇用法,C++的STL作弊器一样,简直kongbu......

所以说,我们一起来看看STL的用法吧!

目录:

1.vector
2.stack
3.queue&priority_queue
4.string
5.map
6.set&multiset
7.list
8.pair
9.bitset
10.algorithm

当然,这只会是一个大致的讲解,不会非常详细



vector

vector,就是不定长数组,内部基于倍增的思想,当数组中有了n个数时(nvector的内存数),vector会申请一个2n的连续空间,把数据拷过去,再释放原来的空间。当数组中的元素<=n/4时,就释放掉一半的空间。也就是说,你想要多少空间就给你多少。

vector支持随机访问,可以直接用如a[i]的方式访问,效率O(1)。

vector声明

1 #include <vector>    //头文件
2 vector<int> a;          //int数组
3 vector<int> k[233]   //第一维长233,第二维变化
4 struct vec_{
5     int x;
6     char name[100]
7 }
8 vector<rec> stru_vec  //自定义的类也能保存在vector中

vector语法

 1 一般的调用:名称.函数名();
 2 size:返回vector的长度。
 3 empty:返回一个bool值,表示vector是否为空。
 4 clear:清空vector
 5 begin/end:返回指向第一个/最后一个元素的迭代器。(*a.begin() 等价于a[0])
 6 front/back:front返回vector的  第一个元素,等价于*a.begin()/a[0]
 7             back 返回vector的最后一个元素,等价于*--a.end()/a[a.size()-1]
 8 push_back/pop_back:
 9 push_back(int x)将x插入到vector的尾部
10 pop_back()删除vector的最后一个元素(不返回值)
11 erase(l,r) 删除[l,r)中的元素(也就是从l到r-1的所有元素)
12 erase(it) 删除位于迭代器it位置的元素

迭代器:

vector区中我们额外讲一下迭代器。

迭代器是STL里面的指针。

一个保存有int数据vector的迭代器声明:

1 vector<int>::iterater it

我们可以用迭代器遍历整个vector:

for(vector<int>::iterater it=a.begin();it!=a,end();++it)  cout<<(*it)<<" ";

vector也支持随机插入:

a.insert(it,x);

在迭代器it处插入x,但vector毕竟不是链表,它的时间复杂度为O(n)。



stack

stack,也就是栈,大家对栈这种数据结构一定不陌生了,而且手写很容易实现 ,但STL中的stack是不定长的

#include <stack>  //定义栈要用的头文件
stack<int> a;   //int类的栈
/*也可以传结构体型啦~*/

stack语法

将元素x放入栈顶: s.push(x);
获得栈顶元素: s.top();
弹出栈顶元素: s.pop();
检查stack是否为空,为空返回1,否则返回0: s.empty();
s.size()/s.empty 用法,用途与stack一样。


queue&priority_queue

queue是队列,先进先出的队列。大家对队列也一定不陌生了,而且手写很容易实现 。

没错,STL中的queue还是不定长的

/*定义方式其实就是把stack哪里的stack改为queue啦~*/

queue的语法

将元素x插入队尾: q.push(x);
获得队首元素: q.front()
弹出队首元素: q.pop();front/back/empty/size还是和stack一样用啦~

 priority_queue

申请n个存放int类型变量的priority_queue:
priority_queue<int>q;

所以priority_queue有什么用呢?

优先队列,其顶部是权值最大的元素,你插入后,它会自动把优先队列里的元素按照权值排好。(其实就是大根堆啦~)

会了priotity_queue,再也不用手写堆啦

priority_queue的语法:

1 priority_queue队首元素最大啦~
2 将元素x插入优先队列: q.push(x);
3 获得队首的元素: q.top()
4 弹出队首的元素: q.pop();
5 让队首元素最小: periority_queue<int> >queue2;

(合并果子是很常见的堆题,那么priority_queue也适合解这种题啦~)



string

作为蒟蒻的我,实在所学不多,再者,string这个东西,肥肠好用,而且包含的函数极多,我这里恐怕写不下,我只能稍微提几点,而且不甚详细,请大家想深究的自行baiduORgoogle一下,顺手贴上一个网址,是一位大佬的博客,总有几篇不错的,这里贴几篇比较详细的,大家可以参阅。

CSDN  cnblog

 string就是字符串,(废话)他需要头文件<cstring>调用(<string>也可以)

它相当于一个字符数组,长度是4294967295(?)

它同样可以用s[i]调用。

string的语法:

int capacity()              //返回当前容量
int max_size()              //返回string对象中可存放的最大字符串的长度
int size()                  //返回当前字符串的大小
int length()                //返回当前字符串的长度
bool empty()                //当前字符串是否为空
void resize(int len,char c);//把字符串当前大小置为len,并用字符c填充不足的部分

差不多先这样啦......



map

map可不要把它理解成数据结构图了,它和图有着本质的区别。映射。map相当于一个数组,但是它的下标可以是各种各样的类,并且只有你申请过的下标才会被储存。

例如你申请一个这样的map: map<string,int> mp; 就可以写 mp["litbleorz"]=233; 这样的语句。  (莫名提到某大佬)

注意:map的复杂度是 O(nlogn) 的。

map的声明:

1 #include <map>      //头文件准备
2 /*然后:*/
3 map<int,int> mp     //话说以int为下标和数组有什么区别

map的语法:

 1 数x元素出现过了几次(其实只有0和1):
 2 mp.count(x)
 3 一个元素是否在map中:
 4 mp.find(x) (但好像速度比count 略慢)
 5 删除元素(迭代器删除: mp.erase(it); 或元素删除:mp.erase(x);)
 6 插入元素:insert(key_type,value_type)
 7 //也就是“下标”和元素的值
 8 /*当然,map作为一个可以当数组实用的东东,可以用mp[i]调用元素的。*/
 9 size/empty/clear/begin/end:
10 //老东西了,分别指:
11 /*元素个数,是否为空,清空,首迭代器,尾迭代器*/


set&multiset

setmultiset的唯一区别只在set会自动去重,multiset不会

他俩的内部实现都基于红黑树,支持函数也基本相同。

所以我们就拿set来举栗子吧。

头文件就不说了。

声明:
set<int> s;
multiset<int> c;
set<rec/*A_struct*/> ss;
但是,set&multiset的类型必须定义了<运算符
插入元素: S.insert(x);                     //O(logn)
删除元素x(参数也可是迭代器): S.erase(x);
返回元素x的迭代器: S.find(x)
查找set内部第一个大于等于x的元素,返回迭代器:lower_bound(x)
查找set内部第一个严格大于x的元素,返回迭代器:upper_bound(x)
size/empty/clear:略。
s.count(x) 数集合中元素x的个数。

大家注意,在multiset中,直接erase(x),会将所有元素x删除!!只需删除一个的要用S.erase(S.find(x));



list

list,就是传说中的链表(手写也很简单,模拟链表更简单)

介绍一下STL中的list

1 头?件: #include<list>
2 1.新建: list<int> lis;
3 2.最后一个元素: lis.back() ;第一个元素:lis.front() 。
4 3.在最后插入一个元素: lis.push_back(); ,最前面:lis.push_front();
5 4.删除最后一个元素: lis.pop_back(); ,最前面:lis.pop_front();
6 5.翻转所有元素: lis.reverse();
7 6.在指定迭代器位置后面插入一个元素:lis.insert(it,x); // 时间复杂度O(1) 

那啥也就这些......



pair

pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如STL中的map就是将key和value放在一起来保存。另一个应用是,当一个函数需要返回2个数据的时候,可以选择pair。 pair的实现是一个结构体,主要的两个成员变量是first&second,而且可以直接用p.first/p.second调用变量(话说自己不能定义结构体吗)

pair的声明:
pair<int, double> p1;         //使用默认构造函数
pair<int, double> p2(1,1.1);  //用给定值初始化
pair<int, double> p3(p2);     //拷贝构造函数

这里直接贴一个pair的链接,我认为讲得比较详细(其实完全可以自己找)



bitset

bitset是一个二进制数。

声明:

bitset<10000> bit;  定义了一个10000位的bitset

为什么要用bitset?位运算不是更好吗?

unsigned long long都不够用时,bitset就来大显身手了,它的大小是很大的。

bitset相当于是一个数组,上面的bit就是一个10000的数组,你自然可以手动编一个bitset ,就每一位每一位地位运算,但那样的复杂度是O(n)的,但bitset的复杂度是O(n/32)的,因为它是将每32位压入了一个int里面(自然,这样也可以压入long long,你可以自己试着手写,这样复杂度就是O(n/64)的了,但奉劝大家没有必要,因为我看见一位大佬手写bitset300多行......)

同样,bitset和普通的数一样,都可以执行这些内容:

~bit      //取反
&,|,^,>>,<<  //与普通数的作用相同
==,!=    //是否相等
[]运算符    // bit[i]表示bit的第i位,可以取赋值。
count()    // 有多少个1
any/none  //若bit值为0(所有位为0),bit.any()=false;bit.none()=true;若bit值不为0(也就是至少一位为1),bit.any()=true;bit.none()=false;
bit.set()   将bit所有位变为1
bit.set(i,x)    将bit第i位变为x,即bit[i]=x;
bit.reset()   把bit所有位归0
bit.reset(i)    把bit第i位归0
bit.flip()      即bit=~bit
bit.flip(i)       将bit第i位取反。


algorithm

algorithm算法库,作弊库

数学

1 max(a,b),min(a,b) :返回a,b中的较大/小值,a,b必须是同种类型的元素
2 abs(x) :取绝对值。
3 fabs(x) :取实数的绝对值时,比abs精度更高。
4 swap(a,b) :交换a,b的值,也可以交换数组/STL,交换数组/STL时,由于是交换指针,所以是 O(1) 的。

sort
排序,左闭右开,复杂度 O(nlog n) ,比手写快排快多了。
排序数组: sort(a+1,a+1+n);
排序STL: sort(a.begin(),a.end());
自定义比较函数:

1 bool cmp(int x,int y) {return x>y;}
2 int main()
3 {
4 sort(a+1,a+1+n,cmp); //从?到?排序
5 return 0;
6 }

reverse

区间翻转,左闭右开,复杂度 O(n) ,比手动翻转快。
数组:reverse(a+1,a+1+n);
STL:reverse(a.begin(),a.end());

next_permutation

求出全排列的字典序下一个排列,例如a,b,c组成的排列,按照字典序有如下排列:

abc,acb,bac,bca,cab,cba

若没有下个排列,则返回值为false。
同理也有prev_permutation,用来求上一个排列

for(int i=1;i<=n;++i) a[i]=i;
do{
    for(int i=1;i<=n;++i) printf("%d" a[i]);
    putchar(‘\n‘);
}while(!next_permutation(a+1,a+1+n));

lower_bound

二分查找,寻找指定区间内第一个大于等于给定权值的值,并返回指针或迭代器,复杂度 O(nlog n) ,比手写二分查找快。

要查找的区间必须按从小到大顺序有序,才能保证返回正确的结果。

还有一个upper_bound,用于查找第一个严格大于给定权值的元素的位置。

for(int i=1;i<=n;++i) a[i]=i;
int k=lower_bound(a+1,a+1+n,3)-a;
cout<<k<<endl;

unique

去重,原理是将所有重复的元素都堆在序列最后?,然后假装它们不存在,返回尾指针/迭代器。要求序列按从小到大有序。

例如你想将 a 这个int类型的数组去重:

int len=unique(a+1,a+1+n)-a-1;

恐怖

希望大家合理利用STL!

原文地址:https://www.cnblogs.com/oierwa-Luogu/p/10320389.html

时间: 2024-11-06 20:42:40

信STL,得永生(STL大法好)的相关文章

C++标准模板库Stand Template Library(STL)简介与STL string类

参考<21天学通C++>第15和16章节,在对宏和模板学习之后,开启对C++实现的标准模板类STL进行简介,同时介绍简单的string类.虽然前面对于vector.deque.list等进行过学习和总结,但并没有一个宏观上的把握,现在通过上一篇和这一篇博文,将对C++模板以及基于C++模板的STL关联起来,形成一个总体的把握,对于掌握C++中模板(template)这一强有力的工具会十分有帮助.本文的主要内容有: (1) STL容器: (2) STL迭代器: (3) STL算法: (4) ST

STL源代码分析——STL算法sort排序算法

前言 因为在前文的<STL算法剖析>中,源代码剖析许多,不方便学习,也不方便以后复习.这里把这些算法进行归类,对他们单独的源代码剖析进行解说.本文介绍的STL算法中的sort排序算法,SGI STL中的排序算法不是简单的高速排序,而是交叉利用各种排序:堆排序.插入排序和高速排序:这样做的目的是提高效率.针对数据量比較大的採用高速排序,数据量比較小的能够採用堆排序或插入排序. 本文介绍了有关排序的算法random_shuffle.partition.stable_partition.sort.s

STL源代码剖析——STL算法之set集合算法

前言 本节介绍set集合的相关算法,各自是并集set_union,差集set_difference,交集set_intersection 和对称差集set_symmetric_difference.这是个函数都提供了两个版本号的函数原型:第一个版本号是採用默认的排序比較方式operator<:第二个版本号是用户通过仿函数comp自行指定排序方式.注意:这四个算法接受的输入区间都是有序的,输出也是有序的. 以下对set算法进行剖析,详细凝视详见源代码,同一时候给出样例说明该算法的功能.本文源代码摘

C++:[STL]详解STL之sequence container的操作及使用(vector)

1.引入 STL,即 standard tempalate library,标准模板库,是C++的重要组成部分.C++ STL(标准模板库)是一套功能强大的 C++ 模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量.链表.队列.栈. STL的构成: 组成部分 描述 iterator(迭代器) 迭代器用于遍历对象集合的元素. container(容器) 容器是用来管理某一类对象的集合. Generic algorithm(泛型算法) 算法作用于容器.

【STL】关于STL中set容器的一些总结

原文链接 关于set,必须说明的是set关联式容器.set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序 1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作.vector封装数组,list封装了链表,map和set封装了二叉树等,在封装这些数据结构

STL之七:STL各种容器的使用时机详解

转载于:http://blog.csdn.net/longshengguoji/article/details/8550235 C++标准程序库提供了各具特长的不同容器.现在的问题是:该如何选择最佳的容器类别?下表给出了概述. 但是其中有些描述可能不一定实际.例如:如果你需呀处理的元素数量很少,可以虎落复杂度,因为线性算法通常对元素本身的处理过程比较快,这种情况下,“显性复杂度搭配快速的元素处理”要比“对数复杂度搭配慢的元素处理”来得划算. 作为对上表的补充,使用时: 1.缺省情况下应该使用ve

STL学习:STL库vector、string、set、map用法

常用方法 vector 1.可随机访问,可在尾部插入元素:2.内存自动管理:3.头文件#include <vector> 1.创建vector对象 一维: (1) vector<int>v1; (2) vector<int>v2(10);//10个元素,初始为0 (3) vector<int>v3(10,4);//10个元素,初始为4 (4) vector<int>v4(v3);//拷贝 (5) vector<int>v5=v4;//

STL版本简介

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 本文的参考文献为:<STL源码剖析>侯捷 (1)HP STL:所有STL的祖先版本,由C++之父Alexander Stepanov和Menge Lee共同完成,可以公开修改但必须在所有的文件中加上HP的版本生命和运用权限声明. (2)PJ STL:继承了HP STL,由P.J.Plauger开发,被微软的Visual C++采用,存放目录为\:msdev\VC98\Include能找到STL头文件,不能公开.修改.贩卖 PJ STL. (3

数据结构(DataStructure)与算法(Algorithm)、STL应用

catalogue 0. 引论 1. 数据结构的概念 2. 逻辑结构实例 2.1 堆栈 2.2 队列 2.3 树形结构 2.3.1 二叉树 3. 物理结构实例 3.1 链表 3.1.1 单向线性链表 3.1.2 单向循环链表 3.1.3 双向线性链表 3.1.4 双向循环链表 3.1.5 数组链表 3.1.6 链表数组 3.1.7 二维链表 3.2 顺序存储 4. 算法 4.1 查找算法 4.2 排序算法 0. 引论 0x1: 为什么要学习数据结构 N.沃思(Niklaus  Wirth)教授提

STL学习一:标准模板库理论基础

STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.现然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间. STL的从广义上讲分为三类:algorithm(算法).container(容器)和iterator(迭代器),容器和算法通过迭代器可以进行无缝 地连接.几乎所有的代码都采 用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会.在C++标准中,STL被组织为下面的13个头文