REF:
区别和api
https://blog.youkuaiyun.com/attitude_yu/article/details/81057988
1.STL组成:
STL有三大核心部分:容器(Container)、算法(Algorithms)、迭代器(Iterator),容器适配器(containeradaptor),函数对象(functor),除此之外还有STL其他标准组件。通俗的讲:
容器:装东西的东西,装水的杯子,装咸水的大海,装人的教室……STL里的容器是可容纳一些数据的模板类。
算法:就是往杯子里倒水,往大海里排污,从教室里撵人……STL里的算法,就是处理容器里面数据的方法、操作。
迭代器:往杯子里倒水的水壶,排污的管道,撵人的那个物业管理人员……STL里的迭代器:遍历容器中数据的对象。对存储于容器中的数据进行处理时,迭代器能从一个成员移向另一个成员。他能按预先定义的顺序在某些容器中的成员间移动。对普通的一维数组、向量、双端队列和列表来说,迭代器是一种指针。
容器: 学习list/vector/deque/set/multisets/map/multimaps/
(1)vector:动态数组,向量。(具体用法看代码)
- #include <iostream>
- #include <stdio.h>
- #include <algorithm>
- #include <string.h>
- #include <queue>
- #include <stack>
- #include <vector>
- #include <list>
- #include <set>
- #include <map>
- using namespace std;
- #define N 10010
- #define LL __int64
- typedef vector<int> INTVECTOR;
- typedef deque<int> INTDEQUE;
- int main() {
- freopen("in.in","r",stdin);
- //freopen("out.out","w",stdout);
- int n,m;
- vector <int> vec1; //vec1初始为空
- vector <int> vec2(10,6); //vec2最初由10个值为6的元素
- vector <int> vec3(vec2.begin(),vec2.begin()+3); //vec3最初由3个值为6的元素。
- //声明迭代器
- vector<int> ::iterator i;
- //从前向后显示vec1中的数据 :迭代器输出使用 *i
- cout<<"vec1.begin()---vec1.end():"<<endl;
- for(i=vec1.begin();i!=vec1.end();i++){
- cout<<*i<<" ";
- }cout<<endl;
- //测试添加和插入成员函数(注意:vector不支持从前插入)
- vec1.push_back(2); //从后面添加一个成员
- vec1.push_back(4);
- vec1.insert(vec1.begin()+1,5); //在vec1的第一个位置上插入成员5
- vec1.insert(vec1.begin()+1,vec3.begin(),vec3.end()); //在vec1的第一个位置上插入vec3的所有成员
- //测试赋值成员函数(重新给vector中的某一位上的元素赋值)
- vec2.assign(8,1); //vec2的8个成员初始值设为1
- //访问vector数组中的某一位置上的元素
- cout<<vec2[2]<<endl;
- //删除和移出
- vec1.pop_back(); //删除vec1的最后一个元素
- vec1.erase(vec1.begin()+1,vec1.end()-2);
- cout<<"vec.pop_back() and vec1.erase():"<<endl;
- for(i=vec1.begin();i!=vec1.end();i++)
- cout<<*i<<" "; cout<<endl;
- //显示序列消息:vector中数组也是从 0 ~ vec1.size(),左闭右开
- //获取vector的大小: vec1.size();
- //清空vector: vec1.clear();
- vec1.clear();
- cout<<"vec1.empty():"<<endl;
- for(i=vec1.begin();i!=vec1.end();i++)
- cout<<*i<<" "; cout<<endl;
- return 0;
- }
(2)queue:双端队列:支持vector不支持的push_front();
- void put_deque(INTDEQUE deque,char *name){
- INTDEQUE::iterator pdeque; //定义迭代器输出
- cout<<"The contents of "<<name<<" : ";
- for(pdeque = deque.begin();pdeque!=deque.end();pdeque++){
- cout<<*pdeque<<" ";
- }cout<<endl;
- }
- int main(){
- //测试deque的各种函数功能
- INTDEQUE deq1;
- INTDEQUE deq2(10,6);
- INTDEQUE:: iterator i;
- //末尾插入元素并打印
- deq1.push_back(2);
- deq1.push_back(4);
- put_deque(deq1,"deq1");
- //前面添加两个元素
- deq1.push_front(5);
- deq1.push_front(7);
- put_deque(deq1,"deq1");
- //中间插入数据
- deq1.insert(deq1.begin()+1,3,9); //插入三个9
- put_deque(deq1,"deq1");
- //数据访问:都表示下坐标
- cout<<deq1[1]<<" "<<deq1.at(5)<<endl;
- //数据删除:从前后,以及按位置删除
- //deq1.pop_front();
- //deq1.pop_back();
- deq1.erase(deq1.begin()+4); //删除下坐标为4的数。
- put_deque(deq1,"deq1");
- //数据修改
- deq1.assign(8,1); //全部赋值为了1
- put_deque(deq1,"deq1");
- deq1.clear(); //清空deque
- put_deque(deq1,"deq1");
- return 0;
- }
(3)list:链表,双向链表,只能顺序访问,不能使用[]进行随机访问
- void printList(list<int> n){
- for(list<int>::iterator i=n.begin();i!=n.end();i++)
- cout<< *i << " ";
- cout<<endl;
- }
- int main(){
- list<int> list1,list2;
- list1.push_back(123);
- list1.push_back(0);
- list1.push_back(34);
- list2.push_back(100);
- list2.push_back(12);
- //测试list排序功能
- printList(list1);
- list1.sort();
- printList(list1);
- list2.sort();
- list1.merge(list2); //两个链表排序后进行合并,合并完仍然有序
- printList(list1);
- return 0;
- }
(4)set和multisets:集和多集:默认是排好序的!
·set:包含元素唯一
·multisets:包含元素可不唯一
- int main(){
- set<int> set1;
- for(int i=0;i<10;i++) set1.insert(i);
- for(set<int>::iterator p = set1.begin();p!=set1.end();p++){
- cout<<*p<<" ";
- }cout<<endl;
- //计算set中值为2的元素个数
- cout<<set1.count(2)<<endl;
- //插入元素:可重复
- multiset<int> A;
- A.insert(set1.begin(),set1.end());
- A.insert(4); //插入之后默认排好序
- for(multiset<int>::iterator i=A.begin();i!=A.end();i++)
- cout<<*i<<" "; cout<<endl;
- return 0;
- }
(5)map和multimaps:映射和多重映射
set中的key和value是Key类型的,而map中的key和value是一个pair结构中的两个分量。Map支持下表运算符operator[],用访问普通数组的方式访问map,不过下标为map的键。在multimap中一个键可以对应多个不同的值。
- int main(){
- //定义map: char是键的类型,int是值的类型
- map<char,int,less<char> > map1;
- map<char,int,less<char> >::iterator mapIter;
- //注意这里: 两个>>符号之间 要有一个空格
- //初始化
- map1['c'] = 3;
- map1['d'] = 4;
- map1['a'] = 1;
- //打印
- for(mapIter=map1.begin();mapIter!=map1.end();mapIter++){
- cout<<" "<<(*mapIter).first<<" : "<<(*mapIter).second;
- }cout<<endl;//其中first对应定义中的char键,second对应定义中的int
- //检索
- map<char,int ,less<char> >::const_iterator t = map1.find('d');
- cout<<"t:"<<(*t).first<<"对应值:"<<(*t).second<<endl;
- cout<<map1['d']<<endl<<endl; //也可以直接这样访问
- //-----------------------multimap------------------------
- multimap<string,string,less<string> >mulmap;
- multimap<string,string,less<string> >::iterator p;
- typedef multimap<string,string,less<string> >::value_type vt;
- //注意multimap中不支持map中的[]下标操作!!!
- //mulmap[string("songjs")] = string("bjfu"); --- 是错误的
- mulmap.insert(vt(string("songjs"),string("is a boy")));
- mulmap.insert(vt(string("songjs"),string("is a girl")));
- //打印输出
- for(p=mulmap.begin();p!=mulmap.end();p++){
- cout<<(*p).first<<" "<<(*p).second<<endl;
- }
- return 0;
- }
注:
1.对于set和map容器,key需要有<操作符或者自定义比较函数
map在STL中的定义
template <class Key, class T, class Compare = less<Key>, class Alloc = alloc>
第一个参数Key是关键字类型
第二个参数T是值类型
第三个参数Compare是比较函数(仿函数)
第四个参数是内存配置对象
map内部存储机制实际是以红黑树为基础,红黑树在插入节点时,必须依照大小比对之后在一个合适的位置上执行插入动作。所以作为关键字,起码必须有“<”这个比较操作符。我们知道,int,float,enum,size_t等等简单关键字,都有内置的比较函数,与map搭配无论是插入还是查找,都没什么问题。但是作为复杂数据类型,如果没有明确定义“<”比较操作符,就不能与map直接搭配使用,除非我们自己定义第三个参数。
在选择map的关键字时,注意以下两点,同时这两点也是改错的方法:
a) 关键字明确定义“<”比较操作符
b) 没有“<”比较操作符,自定义仿函数替代第三个参数Compare,该仿函数实现“()”操作符,提供比较功能。插入时各节点顺序以该仿函数为纲。
https://blog.youkuaiyun.com/zhubaohua_bupt/article/details/62036499