1. 程式人生 > >C++ STL(競賽常用部分)

C++ STL(競賽常用部分)

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.仿函式過載,如優先佇列

相關推薦

no