标签:手写堆 语句 detail 容量 删除元素 rate put 结构 ext
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个数时(n是vector的内存数),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一下,顺手贴上一个网址,是一位大佬的博客,总有几篇不错的,这里贴几篇比较详细的,大家可以参阅。
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
set和multiset的唯一区别只在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!
标签:手写堆 语句 detail 容量 删除元素 rate put 结构 ext
原文地址:https://www.cnblogs.com/oierwa-Luogu/p/10320389.html