C++ STL 总结
為什么80%的碼農都做不了架構師?>>> ??
一、STL的六大組件
1、容器(Container),是一種數(shù)據(jù)結構,如list,vector,和deques ,以模板類的方法提供。為了訪問容器中的數(shù)據(jù),可以使用由容器類輸出的迭代器;
2、迭代器(Iterator),提供了訪問容器中對象的方法。例如,可以使用一對迭代器指定list或vector中的一定范圍的對象。迭代器就如同一個指針。事實上,C++的指針也是一種迭代器。但是,迭代器也可以是那些定義了operator*()以及其他類似于指針的操作符地方法的類對象;
3、算法(Algorithm),是用來操作容器中的數(shù)據(jù)的模板函數(shù)。例如,STL用sort()來對一個vector中的數(shù)據(jù)進行排序,用find()來搜索一個list中的對象,函數(shù)本身與他們操作的數(shù)據(jù)的結構和類型無關,因此他們可以在從簡單數(shù)組到高度復雜容器的任何數(shù)據(jù)結構上使用;
4、仿函數(shù)(Function object,又稱之為函數(shù)對象(function object)),其實就是重載了()操作符的struct,沒有什么特別的地方
5、迭代適配器(Adaptor)
6、空間配制器(allocator),其中主要工作包括兩部分:對象的創(chuàng)建與銷毀、內存的獲取與釋放
以下主要討論:容器,迭代器,算法,適配器:
二、STL容器
1、序列式容器(Sequence containers),每個元素都有固定位置——取決于插入時機和地點,和元素值無關,vector、deque、list
? ?Vectors:將元素置于一個動態(tài)數(shù)組中加以管理,可以隨機存取元素(用索引直接存取),數(shù)組尾部添加或移除元素非常快速。但是在中部或頭部安插元素比較費時;
? ?Deques:是“double-ended queue”的縮寫,可以隨機存取元素(用索引直接存取),數(shù)組頭部和尾部添加或移除元素都非常快速。但是在中部或頭部安插元素比較費時;
? ?Lists:雙向鏈表,不提供隨機存取(按順序走到需存取的元素,O(n)),在任何位置上執(zhí)行插入或刪除動作都非常迅速,內部只需調整一下指針;
2、關聯(lián)式容器(Associated containers),元素位置取決于特定的排序準則,和插入順序無關,set、multiset、map、multimap
? ?Sets/Multisets:內部的元素依據(jù)其值自動排序,Set內的相同數(shù)值的元素只能出現(xiàn)一次,Multisets內可包含多個數(shù)值相同的元素,內部由二叉樹實現(xiàn)(實際上基于紅黑樹(RB-tree)實現(xiàn)),便于查找;
? ?Maps/Multimaps:Map的元素是成對的鍵值/實值,內部的元素依據(jù)其值自動排序,Map內的相同數(shù)值的元素只能出現(xiàn)一次,Multimaps內可包含多個數(shù)值相同的元素,內部由二叉樹實現(xiàn)(實際上基于紅黑樹(RB-tree)實現(xiàn)),便于查找;
另外有其他容器hash_map,hash_set,hash_multiset,hash_multimap
三、STL迭代器?
Iterator(迭代器)模式又稱Cursor(游標)模式,用于提供一種方法順序訪問一個聚合對象中各個元素,?
而又不需暴露該對象的內部表示。
常見的一些迭代器類型:iterator、const_iterator、reverse_iterator和const_reverse_iterator
1、迭代器的使用方法
1)序列式容器(Sequence containers)
std::vector<int> Vec; std::vector<int>::iterator itVec; for( itVec = Vec.begin(); itVec != Vec.end(); ) { if( WillDelete( *itVec) ) { itVec = Vec.erase(itVec); } else itList++; }序列式容器(vector、deque)刪除當前的iterator會使后面所有元素的iterator都失效。這是因為vetor,deque使用了連續(xù)分配的內存,刪除一個元素導致后面所有的元素會向前移動一個位置。還好erase方法可以返回下一個有效的iterator。?
對于list來說,它使用了不連續(xù)分配的內存,并且它的erase方法也會返回下一個有效的iterator,因此關聯(lián)式容器的兩種方法都可以使用。
2)關聯(lián)式容器(Associated containers)
std::list<int> List; std::list<int>::iterator itList; for( itList = List.begin(); itList != List.end(); ) { if( WillDelete( *itList) ) {//方法1itList = List.erase(itList); //方法2List.erase( itList++ ); } else itList++; }關聯(lián)容器刪除當前的iterator,僅僅會使當前的iterator失效,只要在erase時,遞增當前iterator即可。這是因為map之類的容器,使用了紅黑樹來實現(xiàn),插入、刪除一個結點不會對其他結點造成影響。?
2、迭代器失效
1)vector?
內部數(shù)據(jù)結構:數(shù)組。?
隨機訪問每個元素,所需要的時間為常量。?
在末尾增加或刪除元素所需時間與元素數(shù)目無關,在中間或開頭增加或刪除元素所需時間隨元素數(shù)目呈線性變化。?
可動態(tài)增加或減少元素,內存管理自動完成,但程序員可以使用reserve()成員函數(shù)來管理內存。?
vector的迭代器在內存重新分配時將失效(它所指向的元素在該操作的前后不再相同)。當把超過capacity()-size()個元素插入vector中時,內存會重新分配,所有的迭代器都將失效;否則,指向當前元素以后的任何元素的迭代器都將失效。當刪除元素時,指向被刪除元素以后的任何元素的迭代器都將失效。?
2)deque?
內部數(shù)據(jù)結構:數(shù)組。?
隨機訪問每個元素,所需要的時間為常量。?
在開頭和末尾增加元素所需時間與元素數(shù)目無關,在中間增加或刪除元素所需時間隨元素數(shù)目呈線性變化。?
可動態(tài)增加或減少元素,內存管理自動完成,不提供用于內存管理的成員函數(shù)。?
增加任何元素都將使deque的迭代器失效。在deque的中間刪除元素將使迭代器失效。在deque的頭或尾刪除元素時,只有指向該元素的迭代器失效。?
3)list?
內部數(shù)據(jù)結構:雙向環(huán)狀鏈表。?
不能隨機訪問一個元素,可雙向遍歷。?
在開頭、末尾和中間任何地方增加或刪除元素所需時間都為常量。?
可動態(tài)增加或減少元素,內存管理自動完成。?
增加任何元素都不會使迭代器失效。刪除元素時,除了指向當前被刪除元素的迭代器外,其它迭代器都不會失效。?
4)slist?
內部數(shù)據(jù)結構:單向鏈表。?
不可雙向遍歷,只能從前到后地遍歷,其它的特性同list相似。?
5)stack?
適配器,它可以將任意類型的序列容器轉換為一個堆棧,一般使用deque作為支持的序列容器。?
元素只能后進先出(LIFO),不能遍歷整個stack。?
6)queue?
適配器,它可以將任意類型的序列容器轉換為一個隊列,一般使用deque作為支持的序列容器。?
元素只能先進先出(FIFO),不能遍歷整個queue。
7)priority_queue?
適配器,它可以將任意類型的序列容器轉換為一個優(yōu)先級隊列,一般使用vector作為底層存儲方式。?
只能訪問第一個元素,不能遍歷整個priority_queue,第一個元素始終是優(yōu)先級最高的一個元素。
8)set?
鍵和值相等,鍵唯一。?
元素默認按升序排列。?
如果迭代器所指向的元素被刪除,則該迭代器失效。其它任何增加、刪除元素的操作都不會使迭代器失效。
9)multiset?
鍵可以不唯一,其它特點與set相同。?
10)hash_set?
與set相比較,它里面的元素不一定是經過排序的,而是按照所用的hash函數(shù)分派的,它能提供更快的搜索速度(當然跟hash函數(shù)有關),其它特點與set相同。?
11)hash_multiset?
鍵可以不唯一,其它特點與hash_set相同。?
12)map?
鍵唯一,元素默認按鍵的升序排列。?
如果迭代器所指向的元素被刪除,則該迭代器失效。其它任何增加、刪除元素的操作都不會使迭代器失效。
13)multimap?
鍵可以不唯一,其它特點與map相同。?
14)hash_map?
與map相比較,它里面的元素不一定是按鍵值排序的,而是按照所用的hash函數(shù)分派的,它能提供更快的搜索速度(當然也跟hash函數(shù)有關),其它特點與map相同。?
(15)hash_multimap?
鍵可以不唯一,其它特點與hash_map相同。?
四、STL算法
STL算法部分主要由頭文件<algorithm>,<numeric>,<functional>組成。要使用 STL中的算法函數(shù)必須包含頭文件<algorithm>,對于數(shù)值算法須包含<numeric>,<functional>中則定義了一些模板類,用來聲明函數(shù)對象。
以下對所有算法進行細致分類并標明功能:
1、查找算法(13個):判斷容器中是否包含某個值
//在iterator對標識元素范圍內,查找一對相鄰重復元素,找到則返回指向這對元素的第一個元素的ForwardIt //否則返回last。重載版本使用輸入的二元操作符代替相等的判斷 ForwardIt adjacent_find(ForwardIt first, ForwardIt last);//在有序序列中查找value,找到返回true。重載的版本實用指定的比較函數(shù)對象或函數(shù)指針來判斷相等 boo binary_search(ForwardIt first, ForwardIt last, const T& value);//利用等于操作符,把標志范圍內的元素與輸入值比較,返回相等元素個數(shù) size_t count(ForwardIt first, ForwardIt last, const T& value);//利用輸入的操作符,對標志范圍內的元素進行操作,返回結果為true的個數(shù) size_t count_if(ForwardIt first, ForwardIt last, Predicate P);//功能類似equal,返回一對iterator,第一個表示lower_bound,第二個表示upper_bound pair<const_iterator,const_iterator> equal_range (const key_type& k) const; //利用底層元素的等于操作符,對指定范圍內的元素與輸入值進行比較 //當匹配時,結束搜索,返回該元素的一個InputIterator ForwardIt find (ForwardIt first, ForwardIt last, const T& val);//在指定范圍內查找"由輸入的另外一對iterator標志的第二個序列"的最后一次出現(xiàn) //找到則返回最后一對的第一個ForwardIterator,否則返回輸入的"另外一對"的第一個ForwardIt //重載版本使用用戶輸入的操作符代替等于操作 ForwardIt find_end(ForwardIt first1, ForwardIt last, ForwardIt first2, ForwardIt last2);//在指定范圍內查找"由輸入的另外一對iterator標志的第二個序列"中任意一個元素的第一次出現(xiàn) //重載版本中使用了用戶自定義操作符 ForwardIt find_first_of(ForwardIt _First1, ForwardIt _Last1,ForwardIt _First2, ForwardIt _Last2);//使用輸入的函數(shù)代替等于操作符執(zhí)行find InputIterator find_if(ForwardIt first, ForwardIt last, Predicate pred); //返回一個非遞減序列[first, last)中的第一個大于等于值val的位置 ForwardIt lower_bound(ForwardIt first, ForwardIt last, const _Tp& val);//返回的是最后一個大于等于val的位置,也是有一個新元素val進來時的插入位置?????????? ForwardIt upper_bound(ForwardIt first, ForwardIt last, const _Tp& val);//給出兩個范圍,返回一個ForwardIt ,查找成功指向第一個范圍內第一次出現(xiàn)子序列(第二個范圍)的位置 //查找失敗指向last1。重載版本使用自定義的比較操作 ForwardIt search(ForwardIt _First1, ForwardIt _Last1, ForwardIt _First2, ForwardIt _Last2);//在指定范圍內查找val出現(xiàn)n次的子序列。重載版本使用自定義的比較操作。 ForwardIt search_n ( ForwardIt first, ForwardIt last, Size count, const T& value );2、排序和通用算法(14個):提供元素排序策略
//合并兩個有序序列,存放到另一個序列。重載版本使用自定義的比較。 OutputIt merge(InputIt first1, InputIt last1, InputIt first2, InputIt last2,OutputIt result);//合并兩個有序序列,結果序列覆蓋兩端范圍。重載版本使用輸入的操作進行排序。 void inplace_merge(InputIt first, InputIt middle, InputIt last);//將范圍內的序列重新排序,使所有小于第n個元素的元素都出現(xiàn)在它前面,而大于它的都出現(xiàn)在后面。 //重載版本使用自定義的比較操作。 void nth_element(InputIt first, InputIt middle, InputIt last);//該函數(shù)是的將范圍內最小的(middle-frist)個元素放到最前面并且排序 void partial_sort(InputIt first, InputIt middle, InputIt last);//與partial_sort類似,不過將經過排序的序列復制到另一個容器 OutputIt partial_sort_copy(InputIt first, InputIt last, RandomIt result_first, OutputIt result_last);//對指定范圍內元素重新排序,使用輸入的函數(shù),把結果為true的元素放在結果為false的元素之前 OutputIt partition (InputIt first, InputIt last, UnaryPredicate pred);//對指定范圍內的元素隨機調整次序。重載版本輸入一個隨機數(shù)產生操作 void random_shuffle (InputIt first, InputIt last);//將指定范圍內元素重新反序排序 void reverse (InputIt first, InputIt last);//與reverse類似,不過將結果寫入另一個容器 OutputIt reverse_copy (InputIt first, InputIt last, OutputIt result);//將指定范圍內元素移到容器末尾,由middle指向的元素成為容器第一個元素 void rotate (InputIt first, InputIt middle, InputIt last);//與rotate類似,不過將結果寫入另一個容器 OutputIt rotate_copy (InputIt first, InputIt middle, InputIt last, InputIt result);//以升序重新排列指定范圍內的元素,重載版本使用自定義的比較操作 void sort(InputIt first, InputIt last);//與sort類似,不過保留相等元素之間的順序關系 void stable_sort(InputIt first, InputIt last);//與partition類似,不過保證保留容器中的相對順序 OutputIt stable_partition (InputIt first, InputIt last, UnaryPredicate pred);3、刪除和替換算法(15個)
//復制序列 OutputIt copy(InputIt first, InputIt last, OutputIt result);//與copy相同,不過元素是以相反順序被拷貝 OutputIt copy_backward(InputIt first, InputIt last, OutputIt result);//交換兩個InputIt的值 void iter_swap(InputIt a, InputIt b);//刪除指定范圍內所有等于指定元素的元素 //注意,該函數(shù)不是真正刪除函數(shù)。內置函數(shù)不適合使用remove和remove_if函數(shù) OutputIt remove (InputIt first, InputIt last, const T& val);//將所有不匹配元素復制到一個制定容器,返回OutputIterator指向被拷貝的末元素的下一個位置 OutputIt remove_copy (InputIt first, InputIt last, OutputIt result, const T& val);//刪除指定范圍內輸入操作結果為true的所有元素 OutputIt remove_if (InputIt first, InputIt last, UnaryPredicate pred);//將所有不匹配元素拷貝到一個指定容器 OutputIt remove_copy_if (InputIt first, InputIt last, OutputIt result, UnaryPredicate pred);//將指定范圍內所有等于old_value的元素都用new_value代替 void replace (InputIt first, InputIt last, const T& old_value, const T& new_value);//與replace類似,不過將結果寫入另一個容器 OutputIt replace_copy (InputIt first, InputIt last,OutputIt result, const T& old_value, const T& new_value);//將指定范圍內所有操作結果為true的元素用新值代替 void replace_if(InputIt first, InputIt last, UnaryPredicate pred, const T& new_value);//與replace_if,不過將結果寫入另一個容器 OutputIt replace_copy_if (InputIt first, InputIt last,OutputIt result, UnaryPredicate pred, const T& new_value);//交換存儲在兩個對象中的值 void swap (T& a, T& b);//將指定范圍內的元素與另一個序列元素值進行交換(這里已經默認這兩個待交換區(qū)間的長度相等) OutputIt swap_ranges(InputIt _First1, InputIt _Last1, InputIt _First2);//清除序列中重復元素,和remove類似,它也不能真正刪除元素。重載版本使用自定義比較操作。 OutputIt unique (InputIt first, InputIt last);//與unique類似,不過把結果輸出到另一個容器。 OutputIt unique_copy (InputIt first, InputIt last, OutputIt result);4、排列組合算法(2個):提供計算給定集合按一定順序的所有可能排列組合
//取出當前范圍內的排列,并重新排序為下一個排列,重載版本使用自定義的比較操作 bool next_permutation (InputIterator first, InputIterator last);//取出指定范圍內的序列并將它重新排序為上一個序列 //如果不存在上一個序列則返回false,重載版本使用自定義的比較操作 bool prev_permutation (InputIterator first, InputIterator last);5、算術算法(4個)
//iterator對標識的序列段元素之和,加到一個由val指定的初始值上 //重載版本不再做加法,而是傳進來的二元操作符被應用到元素上 T accumulate(InputIt first, InputIt last, T init);//創(chuàng)建一個新序列,其中每個元素值代表指定范圍內該位置前所有元素之和。重載版本使用自定義操作代替加法 OutputIt partial_sum(InputIt first, InputIt last, OutputIt result);//對兩個序列做內積(對應元素相乘,再求和)并將內積加到一個輸入的初始值上。重載版本使用用戶定義的操作 T inner_product(InputIt first1, InputIt last1, InputIt first2, T init);//創(chuàng)建一個新序列,新序列中每個新值代表當前元素與上一個元素的差。重載版本用指定二元操作計算相鄰元素的差 OutputIt adjacent_difference (InputIt first, InputIt last, OutputIt result);6、生成和異變算法(6個)
//將輸入值賦給標志范圍內的所有元素 void fill (InputIt first, InputIt last, const T& val);//將輸入值賦給first到first+n范圍內的所有元素 void fill_n (OutputIt first, Size n, const T& val);//用指定函數(shù)依次對指定范圍內所有元素進行迭代訪問,返回所指定的函數(shù)類型。該函數(shù)不得修改序列中的元素 Function for_each (InputIt first, InputIt last, Function fn);//連續(xù)調用輸入的函數(shù)來填充指定的范圍 void generate (InputIt first, InputIt last, Generator gen);//與generate函數(shù)類似,填充從指定iterator開始的n個元素 void generate_n (OutputIt first, Size n, Generator gen);//將輸入的操作作用于指定范圍內的每個元素,并產生一個新的序列。 //重載版本將操作作用在一對元素上,另外一個元素來自輸入的另外一個序列。結果輸出到指定容器。 OutputIt transform (InputIt first, InputIt last, OutputIt result, UnaryOperation op);?????????????7、關系算法(8個)
//如果兩個序列在標志范圍內元素都相等,返回true。重載版本使用輸入的操作符代替默認的等于操作符 bool equal(InputIt first1, InputIt last1, InputIt first2);//判斷第一個指定范圍內的所有元素是否都被第二個范圍包含,使用底層元素的<操作符,成功返回true //重載版本使用用戶輸入的函數(shù)。 bool includes(InputIt first1, InputIt last1, InputIt first2, InputIt last2);//比較兩個序列,重載版本使用用戶自定義比較操作 bool lexicographical_compare(InputIt first1, InputIt last1, InputIt first2, InputIt last2);//返回兩個元素中較大一個。重載版本使用自定義比較操作 const T& max(const T& a, const T& b);//返回一個OutputIt,指出序列中最大的元素。重載版本使用自定義比較操作 OutputIt max_element(InputIt first, InputIt last);//返回兩個元素中較小一個,重載版本使用自定義比較操作 const T& min(const T& a, const T& b);//返回一個ForwardIterator,指出序列中最小的元素,重載版本使用自定義比較操作 OutputIt min_element (InputIt first, InputIt last);???????? //并行比較兩個序列,指出第一個不匹配的位置,返回一對iterator,標志第一個不匹配元素位置 //如果都匹配,返回每個容器的last。重載版本使用自定義的比較操作 pair<InputIt, InputIt> mismatch (InputIt first1, InputIt last1, InputIt first2);8、集合算法(4個)
//構造一個有序序列,包含兩個序列中所有的不重復元素,重載版本使用自定義的比較操作 OutputIt set_union(InputIt first1, InputIt last1, InputIt first2, InputIt last2, OutputIt result);//構造一個有序序列,其中元素在兩個序列中都存在,重載版本使用自定義的比較操作 OutputIt set_intersection(InputIt first1, InputIt last1, InputIt first2, InputIt last2,OutputIt result);//構造一個有序序列,該序列僅保留第一個序列中存在的而第二個中不存在的元素。重載版本使用自定義的比較操作 OutputIterator set_difference(InputIt first1, InputIt last1, InputIt first2, InputIt last2,OutputIt result);//構造一個有序序列,該序列取兩個序列的對稱差集(并集-交集) OutputIterator set_symmetric_difference(InputIt first1, InputIt last1, InputIt first2, InputIt last2, OutputIt result);9、堆算法(4個)
//把指定范圍內的元素生成一個堆。重載版本使用自定義比較操作 void make_heap(InputIt first, InputIt last);//并不真正把最大元素從堆中彈出,而是重新排序堆。它把first和last-1交換,然后重新生成一個堆 //可使用容器的back來訪問被"彈出"的元素或者使用pop_back進行真正的刪除,重載版本使用自定義的比較操作 void pop_heap(InputIt first, InputIt last);??????????????? //假設first到last-1是一個有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆 //在指向該函數(shù)前,必須先把元素插入容器后,重載版本使用指定的比較操作 void push_heap(InputIt first, InputIt last);//對指定范圍內的序列重新排序,它假設該序列是個有序堆。重載版本使用自定義比較操作 void sort_heap(InputIt first, InputIt last);?????????????
轉載于:https://my.oschina.net/shou1156226/blog/760453
總結
以上是生活随笔為你收集整理的C++ STL 总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#中Uri操作
- 下一篇: linux 安装mysql两种方式