學了這麼長時間的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() 。