STL in ACM入口:https://blog.csdn.net/hahohehehe/article/details/60147328

 

STL大致分为容器,算法,迭代器。几乎所有的代码都采用了模板类和模版函数的方式

常用的算法包括比较,交换,排序等。所有算法的前两个参数都是一对iterator,指出容器内一个范围内的元素。

既然STL代码大都采用了模板类和模版函数的方式,其实自己也是可以实现(如算法之美),但研究具体的实现对于竞赛没有意义,关键熟练运用现成的。

一:算法

sort:以升序重新排列指定范围内的元素。重载版本可使用自定义的比较操作。

swap:交换存储在两个对象中的值。

next_permutation:取出当前范围内的排列,并重新排序为下一个排列。重载版本使用自定义的比较操作。

max:返回两个元素中较大一个。重载版本使用自定义比较操作。

min:返回两个元素中较小一个。重载版本使用自定义比较操作。

例:对于sort,默认升序排序,但可以改变规则:

对于基本数据类型:

 

可利用仿函数:

如:sort(array,array+n,greater<int>());使用greater<datatype>()要加头文件<functional>

可使用重载版本:

如:

bool cmp(int a,int b){

     return a>b;//改变规则为降序

}

sort(array,array+n,cmp);

 

对于非基础数据结构,以结构体为例:

可以在结构体内重载小于运算符

struct node{

      int a;

      bool operator  <(node b){

            return this->a<b.a;//升序

      }

}

sort(array,array+n);

或者:重载sort函数

struct node{

     int c;

}

 

bool cmp(node a,node b){

       return a.c>b.c;

}

sort(array,array+n,cmp);

二:容器

1.list

back() 返回最后一个元素 
begin() 返回指向第一个元素的迭代器 
clear() 删除所有元素 
empty() 如果list是空的则返回true 
end() 返回末尾的迭代器代器 
erase() 删除一个元素 
front() 返回第一个元素 
insert() 插入一个元素到list中 
merge() 合并两个list 
pop_back() 删除最后一个元素 
pop_front() 删除第一个元素 
push_back() 在list的末尾添加一个元素 
push_front() 在list的头部添加一个元素 
rbegin() 返回指向第一个元素的逆向迭代器 
remove() 从list删除元素 
remove_if() 按指定条件删除元素 
rend() 指向list末尾的逆向迭代器 
reverse() 把list的元素倒转 
size() 返回list中的元素个数 
sort() 给list排序  
swap() 交换两个list 

2.stack

empty() 栈为空则返回真

pop() 移除栈顶元素

push() 在栈顶增加元素

size() 返回栈中元素数目

top() 返回栈顶元素

3.queue

push():会将一个元素置入queue中;

front():会返回queue内的第一个元素(也就是第一个被置入的元素)

back():会返回queue中的最后一个元素(也就是最后被插入的元素)

pop():会移除queue内的第一个元素(也就是第一个被置入的元素)

empty()队列为空则返回真

size()返回队列中元素数目

4.priority_queue

push():会将一个元素置入优先队列中;

pop():会移除优先级最高的元素

top():获取优先级最高的元素

empty()为空则返回真

size()返回元素数目

对于优先队列,其中包含很多的构造函数,通过不同构造方式,可以构造不同性质的优先队列

对于基本数据类型(以int为例):

数值大优先级高为默认:priority_queue<int> a

若改变优先级:可以priority_queue<int,vector<int>,greater<int> > a

或者重载仿函数:

struct cmp{  
    bool operator ()(int a,int b){ 
        return a>b;  
    }  
};  
priority_queue <int,vector<int>,cmp> a;

对于非基本数据类型,如结构体,因为结构体未定义小于符号,因此需要在结构体中重载<运算符或者重载仿函数

以默认优先级为例:

结构体中重载<运算符:

struct node{

  int a;

  bool operator < (node data){

     return this->a < data.a;

  }

}

重载仿函数:

 

struct node{

  int a;

}

struct cmp{  
    bool operator ()(node a,node b){ 
        return node.a < node.b;  
    }  
};  
priority_queue <node,vector<node>,cmp> a;

5.vector

push_back()   在数组的最后添加一个数据

pop_back()    去掉数组的最后一个数据 
at()                 得到编号位置的数据
begin()           得到数组头的指针
end()             得到数组的最后一个单元+1的指针
front()            得到数组头的引用
back()            得到数组的最后一个单元的引用
size()             当前使用数据的大小
clear()           清空当前的vector
rbegin()         将vector反转后的开始指针返回(其实就是原来的end-1)
rend()           将vector反转构的结束指针返回(其实就是原来的begin-1)
empty()         判断vector是否为空
swap()          与另一个vector交换数据

6.map

begin()          返回指向map头部的迭代器

clear()         删除所有元素

count()          返回指定元素出现的次数

empty()          如果map为空则返回true
end()             返回指向map末尾的迭代器
erase()          删除一个元素
find()            查找一个元素
insert()         插入元素
rbegin()        返回一个指向map尾部的逆向迭代器
rend()          返回一个指向map头部的逆向迭代器

size()           返回map中元素的个数
swap()          交换两个map

插入数据 
  (1)   my_Map["a"]   =   1; 
  (2)   my_Map.insert(map<string,   int>::value_type("b",2)); 
  (3)   my_Map.insert(pair<string,int>("c",3)); 
  (4)   my_Map.insert(make_pair<string,int>("d",4));

 

map对象的查询操作:

map.count(k) : 返回map中键k的出现次数(对于map而言,由于一个key对应一个value,因此返回只有0和1,因此可以用此函数判断k是否在map中)

map.find(k) :  返回map中指向键k的迭代器,如果不存在键k,则返回end()。

 

移除某个map中某个条目用erase()

该成员方法的定义如下:

  1. iterator erase(iterator it); //通过一个条目对象删除
  2. iterator erase(iterator first, iterator last);        //删除一个范围
  3. size_type erase(const Key& key); //通过关键字删除

7.set

begin()        返回set容器的第一个元素

end()      返回set容器的最后一个元素

clear()         删除set容器中的所有的元素

empty()     判断set容器是否为空

max_size()    返回set容器可能包含的元素最大个数

size()      返回当前set容器中的元素个数

rbegin     返回的值和end()相同

rend()     返回的值和rbegin()相同

求并集和交集:位于algorithm头文件

set_union(s[a].begin(),s[a].end(),s[b].begin(),s[b].end(),inserter(re1,re1.begin()));//结果存在re1集合
set_intersection(s[a].begin(),s[a].end(),s[b].begin(),s[b].end(),inserter(re2,re2.begin()));//结果存在re2集合

count() 用来查找set中某个某个键值出现的次数。这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了。

find()  ,返回给定值值得定位器,如果没找到则返回end()。

insert(key_value); 将key_value插入到set中 ,返回值是pair<set<int>::iterator,bool>,bool标志着插入是否成功,而iterator代表插入的位置,若key_value已经在set中,则iterator表示的key_value在set中的位置。

unordered_map:

例子
int n;
char t[12];
unordered_map <string,int> mymap;
mymap.reserve(n);
cin>>n;
for(int i=1;i<=2*n;i++){
scanf("%s",t);
mymap[t]++;
}
auto i=mymap.cbegin();
string minnumber=i->first;
int count=i->second;
int sum=1;
for(++i;i!=mymap.cend();++i){
if(i->second==count){
sum++;
if(minnumber>i->first)
minnumber=i->first;
}
else if(i->second>count){
sum=1;
count=i->second;
minnumber=i->first;
}
}

注意一:

对于min、max、sort、priority_queue()等用到比较的容器和函数,STL具体实现时都用的是小于运算符,因此若要重载相关运算符,也要重载<运算符,而且改变规则时也要考虑原STL的规则(使用<运算符)在此容器或函数中具体咋实现的功能

注意二:

对于重载:范围很广

1.对于结构体和类,可以重载运算符和函数

2.对于独立函数,不管是具体函数还是模板函数,也可以重载,如除了sort(array,array+n),STL 还有一个模板函数sort(array,array+n,cmp),需码农自己实现

3.子类可以隐藏或者覆盖父类的函数

4.模板类,也可以重载

5.仿函数重载,如优先队列

--------------------- 本文来自 ccDLlyy 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/ccDLlyy/article/details/53264498?utm_source=copy