学了这么长时间的STL库,如今我以为是有必要对过去的题目和所遇到的问题作一下整理了,以便于以后更好的展开练习:node
1、 为何要用STL库? 一、简单粗暴(省事)。 二、便于解决复杂的问题(在贪心题目中显而易见)。 三、使其思路更加普遍,解决问题的角度更多。 2、 怎么用STL库? 一、设身处地的利用某个函数的特色进行解决问题。(下面会进行介绍各个函数的特色) 二、作好第一点就足够了。 3、 各个函数的特色以及适合解决哪些问题? 一、 vector: vector的强大之处就在于能够经过它完成创建邻接表,达到存图、存树的效果,以后利用DFS或者BFS的方式进行解决问题。 最短路(包括其优化)中也会用到Vector. 位置的不一样也能够经过其进行存储:例如那道字符串的题目。 (一个键对应好几个不一样的值时,选择这个会很合适)。 二、 set: set集合的强大之处莫过于它的去重、排序。 尤为是去重,实在是十分之重要,固然,排序也很重要。 三、 map: 键值对:既一个键对应一个值(若要引用键或者值则须要迭代器) 迭代器:map<int,int>::iterator it;(遍历时也须要) 键:it->first,值:it->second; Map会根据键的大小进行自动排序,当有相同元素出现时,用数组的方式的话并不会替代以前已经存在的键值,用insert的方式进行插入的时候会替代已经存在的键值。 四、 queue: 利用队列实现BFS是队列的一个强大功能。 单调队列也能够解决某些问题。 五、 stack 单调栈的应用极其普遍。 单调栈适合解决不可排序的一组数,用来简化时间复杂度。 利用某段数的单调性实现其效果。 六、 priority_queue: 优先级队列内部是经过堆进行实现的。 下面会进行详细介绍。 四:各个函数的相关实现及其属性和方法。 Vector: 1.push_back 在数组的最后添加一个数据 2.pop_back 去掉数组的最后一个数据 3.at 获得编号位置的数据 4.begin 获得数组头的指针 5.end 获得数组的最后一个单元+1的指针 6.front 获得数组头的引用 7.back 获得数组的最后一个单元的引用 8.max_size 获得vector最大能够是多大 9.capacity 当前vector分配的大小 10.size 当前使用数据的大小 11.resize 改变当前使用数据的大小,若是它比当前使用的大,者填充默认值 12.reserve 改变当前vecotr所分配空间的大小 13.erase 删除指针指向的数据项 14.clear 清空当前的vector 15.rbegin 将vector反转后的开始指针返回(其实就是原来的end-1) 16.rend 将vector反转构的结束指针返回(其实就是原来的begin-1) 17.empty 判断vector是否为空 18.swap 与另外一个vector交换数据 3.2 详细的函数实现功能:其中vector<int> c. c.clear() 移除容器中全部数据。 c.empty() 判断容器是否为空。 c.erase(pos) 删除pos位置的数据 c.erase(beg,end) 删除[beg,end)区间的数据 c.front() 传回第一个数据。 c.insert(pos,elem) 在pos位置插入一个elem拷贝 c.pop_back() 删除最后一个数据。 c.push_back(elem) 在尾部加入一个数据。 c.resize(num) 从新设置该容器的大小 c.size() 回容器中实际数据的个数。 c.begin() 返回指向容器第一个元素的迭代器 c.end() 返回指向容器最后一个元素的迭代器 set: begin() 返回set容器的第一个迭代器 end() 返回set容器的最后一个迭代器 clear() 删除set容器中的全部的元素 empty() 判断set容器是否为空 max_size() 返回set容器可能包含的元素最大个数 size() 返回当前set容器中的元素个数 rbegin 返回的值和end()相同 rend() 返回的值和rbegin()相同 判断某个元素是否出如今set集合中的两种方法: 一、COUNT() 用来查找SET中某个某个键值出现的次数。这个函数在SET并非很实用,由于一个键值在SET只可能出现0或1次,这样就变成了判断某一键值是否在SET出现过了。 示例代码: #include <iostream> #include <set> using namespace std; int main() { set<int> s; s.insert(1); s.insert(2); s.insert(3); s.insert(1); cout<<"set 中 1 出现的次数是 :"<<s.count(1)<<endl; cout<<"set 中 4 出现的次数是 :"<<s.count(4)<<endl; return 0; } 二、 FIND() ,返回给定值值得定位器,若是没找到则返回END()。 #include <iostream> #include <set> using namespace std; int main() { int a[] = {1,2,3}; set<int> s(a,a+3); set<int>::iterator iter; if((iter = s.find(2)) != s.end()) { cout<<*iter<<endl; } return 0; } #Set中的删除操做:# 一、erase(iterator) ,删除定位器iterator指向的值 二、erase(first,second),删除定位器first和second之间的值 三、erase(key_value),删除键值key_value的值 #include <iostream> #include <set> using namespace std; int main() { set<int> s; set<int>::const_iterator iter; set<int>::iterator first; set<int>::iterator second; for(int i = 1 ; i <= 10 ; ++i) { s.insert(i); } //第一种删除 s.erase(s.begin()); //第二种删除 first = s.begin(); second = s.begin(); second++; second++; s.erase(first,second); //第三种删除 s.erase(8); cout<<"删除后 set 中元素是 :"; for(iter = s.begin() ; iter != s.end() ; ++iter) { cout<<*iter<<" "; } cout<<endl; return 0; } 二分查找: lower_bound(key_value) ,返回第一个大于等于key_value的定位器 upper_bound(key_value),返回最后一个大于等于key_value的定位器 #include <iostream> #include <set> using namespace std; int main() { set<int> s; s.insert(1); s.insert(3); s.insert(4); cout<<*s.lower_bound(2)<<endl; cout<<*s.lower_bound(3)<<endl; cout<<*s.upper_bound(3)<<endl; return 0; } Map: begin() 返回指向map头部的迭代器 clear() 删除全部元素 count() 返回指定元素出现的次数 empty() 若是map为空则返回true end() 返回指向map末尾的迭代 equal_range() 返回特殊条目的迭代器 erase() 删除一个元素 find() 查找一个元素 get_allocator() 返回map的配置器 insert() 插入元素 key_comp() 返回比较元素key的函数 lower_bound() 返回键值>=给定元素的第一个位置 max_size() 返回能够容纳的最大元素个数 rbegin() 返回一个指向map尾部的逆向迭代器 rend() 返回一个指向map头部的逆向迭代器 size() 返回map中元素的个数 swap() 交换两个map upper_bound() 返回键值>给定元素的第一个位置 value_comp() 返回比较元素value的函数 Queue: back()返回最后一个元素 empty()若是队列空则返回真 front()返回第一个元素 pop()删除第一个元素 push()在末尾加入一个元素 size()返回队列中元素的个数 访问: q.front(),即最先被压入队列的元素。 q.back(),即最后被压入队列的元素。 Privority_queue: 入队 q.push(); 出队 q.pop(); 求队列中元素个数 q.size(); 判断队列是否为空 q.empty();若为空返回true,不然返回false 得到首元素 q.top(); 返回q的第一个元素 q.top(); 返回q的末尾元素 q.back(); 优先级里最重要的东西:排序: 默认的优先队列 priority_queue <int> q;排序是由大到小的: #include<stdio.h> #include<queue> using namespace std; int main() { priority_queue<int> q; int num[5]={19,2,4,3,6}; for(int i=0;i<5;i++) q.push(num[i]); for(int i=0;i<5;i++) { int temp=q.top(); printf("%d ",temp); q.pop(); } return 0; } 默认的优先队列(结构体,重载小于) #include<stdio.h> #include<queue> using namespace std; struct node { int x,y; bool operator < (const node & a) const { return x<a.x; } }s; struct node { int x; int y; int time; friend bool operator < (node n1, node n2) // 也能够用友元函数friend { return n1.time>n2.time; } }; priority_queue <node> q; int main() { printf("读入:\n"); for(int i=0;i<5;i++) { scanf("%d%d",&s.x,&s.y); q.push(s); } printf("输出:\n"); while(!q.empty()) { node temp=q.top(); printf("(%d,%d) ",temp.x,temp.y); q.pop(); } return 0; } less是从大到小,greater是从小到大: //升序队列 priority_queue <int,vector<int>,greater<int> > q; //降序队列 priority_queue <int,vector<int>,less<int> >q; //greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了相似函数的行为,就是一个仿函数类了) 优先级与结构体: #include <iostream> #include <queue> using namespace std; struct Node{ int x, y; Node(int a=0, int b=0): x(a),y(b){} }; bool operator<(Node a, Node b){//返回true时,说明a的优先级低于b //x值较大的Node优先级低(x小的Node排在队前) //x相等时,y大的优先级低(y小的Node排在队前) if( a.x== b.x ) return a.y< b.y; //优先级队列中的结构体与以前的覆写函数有些许的不一样,< 表明从大的先出队 return a.x< b.x; } int main(){ priority_queue<Node> q; for( int i= 0; i< 5; ++i ){ int a,b; scanf("%d%d",&a,&b); q.push({a,b}); } while( !q.empty() ){ cout << q.top().x << ' ' << q.top().y << endl; q.pop(); } return 0; } Stack: 入栈,如例:s.push(x); 出栈,如例:s.pop();注意,出栈操做只是删除栈顶元素,并不返回该元素。 访问栈顶,如例:s.top() 判断栈空,如例:s.empty() ,当栈空时,返回true。 访问栈中的元素个数,如例:s.size() 。