亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

蟲蟲首頁| 資源下載| 資源專輯| 精品軟件
登錄| 注冊

您現在的位置是:首頁 > 技術閱讀 >  萬字長文 | STL 算法總結

萬字長文 | STL 算法總結

時間:2024-02-10

本篇所有算法源碼均已同步收錄 GitHub 倉庫,歡迎點個小??:https://github.com/rongweihe/CPPNotes/tree/master/STL-source-code-notes

STL 算法博大精深,涵蓋范圍之廣,其算法之大觀,細節之深入,泛型思維之于字里行間,每每閱讀都會有不同的收獲。

STL 將很多常見的邏輯都封裝為現成的算法,熟悉這些算法的使用和實現很多時候可以大大簡化編程。

并且在需要的時候能夠對 STL 進行擴展,將自定義的容器和算法融入到 STL 中。

侯捷大師在書中說到:深入源碼之前,先觀察每一個算法的表現和大觀,是一個比較好的學習方式。

不多 BB,先上思維導圖:

回顧

STL 源碼剖析系列:

5 千字長文+ 30 張圖解 | 陪你手撕 STL 空間配置器源碼
萬字長文炸裂!手撕 STL 迭代器源碼與 traits 編程技法
超硬核 | 2 萬字+20 圖帶你手撕 STL 序列式容器源碼
硬核來襲  | 2 萬字 + 10 圖帶你手撕 STL 關聯式容器源碼

基本算法

在 STL 標準規格中,并沒有區分基本算法或復雜算法,然而 SGI 卻把常用的一些算法定義于 <stl_algobase.h>之中,其它算法定義于 <stl_algo.h>中。

常見的基本算法有 equal、fill、fill_n、iter_swap、lexicographical_compare、max、min、mismatch、swap、copy、copy_backward 等。

質變算法和非質變算法

所有的 STL 算法歸根到底,都可以分為兩類。

所謂“質變算法”是指作用在由迭代器[first,last]所標示出來的區間,上運算過程中會更改區間內的元素內容:

比如拷貝(copy)、互換(swap)、替換(replace)、填寫(fill)、刪除(remove)、排列組合(permutation)、分割(partition)。隨機重排(random shuffling)、排序(sort)等算法,都屬于這一類。

而非質變算法是指在運算過程中不會更改區間內的元素內容。比如查找(find),匹配(search)、計數(count)、遍歷(for_each)、比較(equal_mismatch)、尋找極值(max,min)等算法。

輸入參數

所有泛型算法的前兩個參數都是一對迭代器,通過稱為 first,last 用來標示算法的操作區間。

每一個 STL 算法的聲明,都表現出它所需要的最低程度的迭代器類型。

比如 find() 需要一個 inputiterator ,這是它的最低要求,但同時也可以接受更高類型的迭代器。

如 Forwarditerator、Bidirectionaliterator 或 RandomAcessIterator。

因為,前者都可以看做是一個 inputiterator,而如果你給 find() 傳入一個 Outputiterator,會導致錯誤。

將無效的迭代器傳給某個算法,雖然是一種錯誤,但不保證能夠在編譯器期間就被捕捉出來。

因為所謂“迭代器類型”并不是真實的型別,它們只是function template的一種型別參數。

許多 STL 算法不僅支持一個版本,往往第一個版本算法會采用默認的行為,另一個版本會提供額外的參數,接受一個仿函數,以便采取其它的策略。

例如 unique() 默認情況下會使用 equality 操作符來比較兩個相鄰元素,但如果這些元素的型別并沒有提供,那么便可以傳遞一個自定義的函數(或者叫仿函數)。

知道了這一點,對于想要深入研究源碼的小伙伴們會更好理解一些。

算法的泛型化

將一個表述完整的算法轉化為程序代碼,是一個合格程序員的基本功。

如何將算法獨立于其所處理的數據結構之外,不受數據的牽絆,使得設計的算法在即將處理的未知的數據結構上(也許是 array,也許是 vector,也許是 list,也許是 deque)上,正確地實現所有操作呢?

這就需要進一步思考:關鍵在于只要把操作對象的型別加以抽象化,把操作對象的標示法和區間目標的移動行為抽象化,整個算法也就在一個抽象層面上工作了。

這個過程就叫做算法的泛型化,簡稱泛化。

比如在 STL 源碼剖析這本書里舉了一個 find 的例子,如果一步步改成 template + 迭代器的形式,來說明了泛化的含義。

下面我們就來看看 STL 那些牛批的算法,限于篇幅,算法的代碼沒有貼出。

具體源碼細節可以去開頭的 GitHub 倉庫里研究,還有注釋哦。

構成

頭文件功能
<algorithm>算法函數
<numeric>數值算法
<functional>函數對象/仿函數

分類

No.分類說明
1非質變算法Non-modifying sequence operations不直接修改容器內容的算法
2質變算法Modifying sequence operations可以修改容器內容的算法
3排序算法Sorting/Partitions/Binary search/對序列排序、合并、搜索算法操作
4數值算法Merge/Heap/Min/max對容器內容進行數值計算

填充

函數作用
fill(beg,end,val)將值val賦給[beg,end)范圍內的所有元素
fill_n(beg,n,val)將值val賦給[beg,beg+n)范圍內的所有元素
generate(beg,end,func)連續調用函數func填充[beg,end)范圍內的所有元素
generate_n(beg,n,func)連續調用函數func填充[beg,beg+n)范圍內的所有元素
  • fill()/fill_n()用于填充相同值,generate()/generate_n()用于填充不同值。

遍歷/變換

函數作用
for_each(beg,end,func)將[beg,end)范圍內所有元素依次調用函數func,返回func。不修改序列中的元素
transform(beg,end,res,func)將[beg,end)范圍內所有元素依次調用函數func,結果放入res
transform(beg2,end1,beg2,res,binary)將[beg,end)范圍內所有元素與[beg2,beg2+end-beg)中所有元素依次調用函數binnary,結果放入res

最大最小

函數作用
max(a,b)返回兩個元素中較大一個
max(a,b,cmp)使用自定義比較操作cmp,返回兩個元素中較大一個
max_element(beg,end)返回一個ForwardIterator,指出[beg,end)中最大的元素
max_element(beg,end,cmp)使用自定義比較操作cmp,返回一個ForwardIterator,指出[beg,end)中最大的元素
min(a,b)返回兩個元素中較小一個
min(a,b,cmp)使用自定義比較操作cmp,返回兩個元素中較小一個
min_element(beg,end)返回一個ForwardIterator,指出[beg,end)中最小的元素
min_element(beg,end,cmp)使用自定義比較操作cmp,返回一個ForwardIterator,指出[beg,end)中最小的元素

排序算法(12個):元素排序策略

函數作用
sort(beg,end)默認升序重新排列元素
sort(beg,end,comp)使用函數comp代替比較操作符執行sort()
partition(beg,end,pred)元素重新排序,使用pred函數,把結果為true的元素放在結果為false的元素之前
stable_sort(beg,end)sort()類似,保留相等元素之間的順序關系
stable_sort(beg,end,pred)使用函數pred代替比較操作符執行stable_sort()
stable_partition(beg,end)partition()類似,保留容器中的相對順序
stable_partition(beg,end,pred)使用函數pred代替比較操作符執行stable_partition()
partial_sort(beg,mid,end)部分排序,被排序元素個數放到[beg,end)內
partial_sort(beg,mid,end,comp)使用函數comp代替比較操作符執行partial_sort()
partial_sort_copy(beg1,end1,beg2,end2)partial_sort()類似,只是將[beg1,end1)排序的序列復制到[beg2,end2)
partial_sort_copy(beg1,end1,beg2,end2,comp)使用函數comp代替比較操作符執行partial_sort_copy()
nth_element(beg,nth,end)單個元素序列重新排序,使所有小于第n個元素的元素都出現在它前面,而大于它的都出現在后面
nth_element(beg,nth,end,comp)使用函數comp代替比較操作符執行nth_element()

反轉/旋轉

函數作用
reverse(beg,end)元素重新反序排序
reverse_copy(beg,end,res)reverse()類似,結果寫入res
rotate(beg,mid,end)元素移到容器末尾,由mid成為容器第一個元素
rotate_copy(beg,mid,end,res)rotate()類似,結果寫入res

隨機

函數作用
random_shuffle(beg,end)元素隨機調整次序
random_shuffle(beg,end,gen)使用函數gen代替隨機生成函數執行random_shuffle()

查找算法(13個):判斷容器中是否包含某個值

統計

函數作用
count(beg,end,val)利用==操作符,對[beg,end)的元素與val進行比較,返回相等元素個數
count_if(beg,end,pred)使用函數pred代替==操作符執行count()

查找

函數作用
find(beg,end,val)利用==操作符,對[beg,end)的元素與val進行比較。當匹配時結束搜索,返回該元素的InputIterator
find_if(beg,end,pred)使用函數pred代替==操作符執行find()
find_first_of(beg1,end1,beg2,end2)在[beg1,end1)范圍內查找[beg2,end2)中任意一個元素的第一次出現。返回該元素的Iterator
find_first_of(beg1,end1,beg2,end2,pred)使用函數pred代替==操作符執行find_first_of()。返回該元素的Iterator
find_end(beg1,end1,beg2,end2)在[beg1,end1)范圍內查找[beg2,end2)最后一次出現。找到則返回最后一對的第一個ForwardIterator,否則返回end1
find_end(beg1,end1,beg2,end2,pred)使用函數pred代替==操作符執行find_end()。返回該元素的Iterator
adjacent_find(beg,end)對[beg,end)的元素,查找一對相鄰重復元素,找到則返回指向這對元素的第一個元素的ForwardIterator。否則返回end
adjacent_find(beg,end,pred)使用函數pred代替==操作符執行adjacent_find()

搜索

函數作用
search(beg1,end1,beg2,end2)在[beg1,end1)范圍內查找[beg2,end2)首一次出現,返回一個ForwardIterator,查找成功,返回[beg1,end1)內第一次出現[beg2,end2)的位置,查找失敗指向end1
search(beg1,end1,beg2,end2,pred)使用函數pred代替==操作符執行search()
search_n(beg,end,n,val)在[beg,end)范圍內查找val出現n次的子序列
search_n(beg,end,n,val,pred)使用函數pred代替==操作符執行search_n()
binary_search(beg,end,val)二分查找,在[beg,end)中查找val,找到返回true
binary_search(beg,end,val,comp)使用函數comp代替比較操作符執行binary_search()

邊界

函數作用
lower_bound(beg,end,val)在[beg,end)范圍內的可以插入val而不破壞容器順序的第一個位置,返回一個ForwardIterator(返回范圍內第一個大于等于值val的位置)
lower_bound(beg,end,val,comp)使用函數comp代替比較操作符執行lower_bound()
upper_bound(beg,end,val)在[beg,end)范圍內插入val而不破壞容器順序的最后一個位置,該位置標志一個大于val的值,返回一個ForwardIterator(返回范圍內第一個大于val的位置)
upper_bound(beg,end,val,comp)使用函數comp代替比較操作符執行upper_bound()
equal_range(beg,end,val)返回一對iterator,第一個表示lower_bound,第二個表示upper_bound
equal_range(beg,end,val,comp)使用函數comp代替比較操作符執行lower_bound()

刪除和替換算法(15個)

復制

函數作用
copy(beg,end,res)復制[beg,end)到res
copy_backward(beg,end,res)copy()相同,不過元素是以相反順序被拷貝

移除

函數作用
remove(beg,end,val)移除[first,last)區間內所有與val值相等的元素,并不是真正的從容器中刪除這些元素(原容器的內容不會改變)而是將結果復制到一個以result為起始位置的容器中。新容器可以與原容器重疊
remove_if(beg,end,pred)刪除[beg,end)pred結果為true的元素
remove_copy(beg,end,res,val)將所有不等于val元素復制到res,返回OutputIterator指向被拷貝的末元素的下一個位置
remove_copy_if(beg,end,res,pred)將所有使pred結果為true的元素拷貝到res

替換

函數作用
replace(beg,end,oval,nval)將[beg,end)內所有等于oval的元素都用nval代替
replace_copy(beg,end,res,oval,nval)replace()類似,不過將結果寫入res
replace_if(beg,end,pred,nval)將[beg,end)內所有predtrue的元素用nval代替
replace_copy_if(beg,end,res,pred,nval)replace_if(),不過將結果寫入res

去重

函數作用
unique(beg,end)清除序列中相鄰重復元素,不真正刪除元素。重載版本使用自定義比較操作
unique(beg,end,pred)將所有使pred結果為true的相鄰重復元素去重
unique_copy(beg,end,res)unique類似,不過把結果輸出到res
unique_copy(beg,end,res,pred)unique類似,不過把結果輸出到res

交換

函數作用
swap(a,b)交換存儲在ab中的值
swap_range(beg1,end1,beg2)將[beg1,end1)內的元素[beg2,beg2+beg1-end1)元素值進行交換
iter_swap(it_a,it_b)交換兩個ForwardIterator的值

算術算法(4個)

函數作用
accumulate(beg,end,val)對[beg,end)內元素之和,加到初始值val
accumulate(beg,end,val,binary)將函數binary代替加法運算,執行accumulate()
partial_sum(beg,end,res)將[beg,end)內該位置前所有元素之和放進res
partial_sum(beg,end,res,binary)將函數binary代替加法運算,執行partial_sum()
adjacent_difference(beg1,end1,res)將[beg,end)內每個新值代表當前元素與上一個元素的差放進res
adjacent_difference(beg1,end1,res,binary)將函數binary代替減法運算,執行adjacent_difference()
inner_product(beg1,end1,beg2,val)對兩個序列做內積(對應元素相乘,再求和)并將內積加到初始值val
inner_product(beg1,end1,beg2,val,binary1,binary2)將函數binary1代替加法運算,將binary2代替乘法運算,執行inner_product()

關系算法(4個)

函數作用
equal(beg1,end1,beg2)判斷[beg1,end1)與[beg2,end2)內元素都相等
equal(beg1,end1,beg2,pred)使用pred函數代替默認的==操作符
includes(beg1,end1,beg2,end2)判斷[beg1,end1)是否包含[beg2,end2),使用底層元素的<操作符,成功返回true。重載版本使用用戶輸入的函數
includes(beg1,end1,beg2,end2,comp)將函數comp代替<操作符,執行includes()
lexicographical_compare(beg1,end1,beg2,end2)按字典序判斷[beg1,end1)是否小于[beg2,end2)
lexicographical_compare(beg1,end1,beg2,end2,comp)將函數comp代替<操作符,執行lexicographical_compare()
mismatch(beg1,end1,beg2)并行比較[beg1,end1)與[beg2,end2),指出第一個不匹配的位置,返回一對iterator,標志第一個不匹配元素位置。如果都匹配,返回每個容器的end
mismatch(beg1,end1,beg2,pred)使用pred函數代替默認的==操作符

集合算法(6個)

函數作用
merge(beg1,end1,beg2,end2,res)合并[beg1,end1)與[beg2,end2)存放到res
merge(beg1,end1,beg2,end2,res,comp)將函數comp代替<操作符,執行merge()
inplace_merge(beg,mid,end)合并[beg,mid)與[mid,end),結果覆蓋[beg,end)
inplace_merge(beg,mid,end,cmp)將函數comp代替<操作符,執行inplace_merge()
set_union(beg1,end1,beg2,end2,res)取[beg1,end1)與[beg2,end2)元素并集存放到res
set_union(beg1,end1,beg2,end2,res,comp)將函數comp代替<操作符,執行set_union()
set_intersection(beg1,end1,beg2,end2,res)取[beg1,end1)與[beg2,end2)元素交集存放到res
set_intersection(beg1,end1,beg2,end2,res,comp)將函數comp代替<操作符,執行set_intersection()
set_difference(beg1,end1,beg2,end2,res)取[beg1,end1)與[beg2,end2)元素內差集存放到res
set_difference(beg1,end1,beg2,end2,res,comp)將函數comp代替<操作符,執行set_difference()
set_symmetric_difference(beg1,end1,beg2,end2,res)取[beg1,end1)與[beg2,end2)元素外差集存放到res

排列組合算法:提供計算給定集合按一定順序的所有可能排列組合

函數作用
next_permutation(beg,end)取出[beg,end)內的下移一個排列
next_permutation(beg,end,comp)將函數comp代替<操作符,執行next_permutation()
prev_permutation(beg,end)取出[beg,end)內的上移一個排列
prev_permutation(beg,end,comp)將函數comp代替<操作符,執行prev_permutation()

堆算法(4個)

函數作用
make_heap(beg,end)把[beg,end)內的元素生成一個堆
make_heap(beg,end,comp)將函數comp代替<操作符,執行make_heap()
pop_heap(beg,end)重新排序堆。它把first和last-1交換,然后重新生成一個堆。可使用容器的back來訪問被"彈出"的元素或者使用pop_back進行真正的刪除。并不真正把最大元素從堆中彈出
pop_heap(beg,end,comp)將函數comp代替<操作符,執行pop_heap()
push_heap(beg,end)假設first到last-1是一個有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。在指向該函數前,必須先把元素插入容器后
push_heap(beg,end,comp)將函數comp代替<操作符,執行push_heap()
sort_heap(beg,end)對[beg,end)內的序列重新排序
sort_heap(beg,end,comp)將函數comp代替<操作符,執行push_heap()

參考:

《STL源碼剖析》-侯捷

https://www.jianshu.com/p/eb554b0943ab

感謝你的閱讀,歡迎點贊,在看,留言,加我好友一起交流



往期推薦



2021程序喵技術年貨

【性能優化】lock-free在召回引擎中的實現

定下來了!

SDK開發的一些思考

Linux中對【庫函數】的調用進行跟蹤的 3 種【插樁】技巧

【線上問題】P1級公司故障,年終獎不保

探索CPU的調度原理

防御性編程技巧

C++的全鏈路追蹤方案,稍微有點高端

多線程程序中操作的原子性


亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美一区视频在线| 亚洲人在线视频| 免费亚洲电影| 另类国产ts人妖高潮视频| 美腿丝袜亚洲色图| 欧美激情五月| 国产精品一区二区女厕厕| 国产情人综合久久777777| 精品不卡在线| 亚洲影院在线观看| 欧美成人资源| 国内精品久久久久久影视8| 亚洲精品小视频在线观看| 午夜精品在线| 欧美精品国产| 一区在线影院| 欧美呦呦网站| 欧美网站在线观看| 91久久精品国产91久久性色tv| 亚洲资源在线观看| 欧美精品在线极品| 国产精品视频xxx| 亚洲区一区二区三区| 久久免费视频网站| 国产午夜精品一区二区三区视频| 一本色道久久综合亚洲精品高清| 麻豆国产va免费精品高清在线| 国产欧美日韩另类一区| 制服丝袜亚洲播放| 欧美日韩专区在线| 中国女人久久久| 欧美日韩国产区| 日韩性生活视频| 欧美精品二区| 99riav1国产精品视频| 欧美日韩精品系列| 日韩午夜在线电影| 欧美三级网址| 亚洲在线免费视频| 国产精品中文字幕欧美| 亚洲欧美国产一区二区三区| 国产精品久久久久久久久久三级 | 欧美激情偷拍| 亚洲电影一级黄| 卡通动漫国产精品| 亚洲经典视频在线观看| 欧美国产视频在线| 一本色道久久综合亚洲精品按摩| 国产精品爱久久久久久久| 亚洲综合色网站| 国产一区二区三区四区三区四| 欧美一激情一区二区三区| 好吊妞**欧美| 欧美精品不卡| 欧美一区成人| 国产又爽又黄的激情精品视频| 蜜臀久久99精品久久久久久9| 亚洲美女啪啪| 国产日本欧美一区二区三区在线| 欧美制服第一页| 亚洲黄色小视频| 国产欧亚日韩视频| 欧美精品久久一区二区| 午夜一区不卡| 亚洲精品字幕| 国产一区二区三区高清播放| 欧美国内亚洲| 先锋影音国产精品| 亚洲精品日本| 国产视频一区三区| 欧美精品在线极品| 久久综合999| 欧美在线播放视频| 99在线精品视频| 精品电影一区| 国产人妖伪娘一区91| 欧美日韩视频不卡| 免费成人黄色av| 久久成人免费网| 亚洲免费在线播放| 99精品热6080yy久久 | 久久久天天操| 亚洲欧美视频在线| 一本色道久久综合亚洲精品按摩| 国内揄拍国内精品久久| 国产精品成人一区二区网站软件| 久久久精品国产99久久精品芒果| 亚洲午夜视频在线观看| 日韩视频一区二区三区| 亚洲电影免费观看高清完整版在线观看| 国产精品久久久久久久午夜| 欧美日韩国产经典色站一区二区三区| 久久人91精品久久久久久不卡| 亚洲影音先锋| 亚洲永久在线| 亚洲一区二区三区欧美| 99热精品在线| 一区二区免费在线观看| 欧美成人免费全部| 久久精品首页| 欧美一级视频| 午夜在线一区| 欧美伊人久久久久久午夜久久久久| 一本一本a久久| 亚洲天堂成人在线视频| 亚洲天堂av图片| 亚洲欧美色一区| 久久久噜噜噜久久久| 老司机精品久久| 欧美aaaaaaaa牛牛影院| 欧美激情亚洲综合一区| 欧美人成在线视频| 欧美午夜激情在线| 国产欧美不卡| 黄色在线成人| 日韩手机在线导航| 亚洲永久精品国产| 久久久精品一品道一区| 久久综合网络一区二区| 欧美韩国一区| 国产精品系列在线播放| 激情成人在线视频| 亚洲美女视频在线免费观看| 亚洲性感激情| 久久在线观看视频| 欧美日韩国产综合视频在线观看中文 | 久久综合999| 狂野欧美激情性xxxx欧美| 久久深夜福利| 欧美精品xxxxbbbb| 国产精品毛片在线看| 国产日韩一级二级三级| 在线成人激情视频| 亚洲午夜av| 久久婷婷国产综合精品青草| 欧美日本国产一区| 韩国一区二区在线观看| 亚洲视频观看| 蜜臀久久99精品久久久画质超高清| 欧美四级剧情无删版影片| 狠狠久久五月精品中文字幕| 9色精品在线| 久久久久www| 欧美性一区二区| 亚洲国产精品电影在线观看| 午夜在线视频一区二区区别| 欧美激情国产日韩| 韩曰欧美视频免费观看| 亚洲视频久久| 欧美福利电影在线观看| 国产色爱av资源综合区| 一区二区激情| 欧美二区不卡| 狠狠久久亚洲欧美| 亚洲伊人网站| 欧美日韩调教| 99re成人精品视频| 老司机67194精品线观看| 国产精品视频精品| 亚洲桃花岛网站| 欧美视频在线一区二区三区| 亚洲人成毛片在线播放女女| 久久亚洲一区| 尤物网精品视频| 美国三级日本三级久久99| 国模私拍一区二区三区| 欧美伊人影院| 国产欧美va欧美不卡在线| 亚洲欧美高清| 国产精品视频免费在线观看| 中文网丁香综合网| 欧美日韩另类一区| av成人毛片| 欧美色123| 亚洲午夜在线视频| 国产精品卡一卡二卡三| 中文精品视频一区二区在线观看| 欧美日韩精品免费观看视频| 日韩一区二区精品在线观看| 欧美国产日韩一区二区三区| 亚洲黄网站在线观看| 欧美国产日本在线| 亚洲精品社区| 欧美日韩中文字幕在线视频| 亚洲自啪免费| 韩国美女久久| 欧美黄色小视频| 亚洲视频在线观看视频| 国产精品久久久99| 欧美在线免费播放| 亚洲大片在线| 欧美精品系列| 亚洲午夜在线观看| 国产喷白浆一区二区三区| 久久伊人一区二区| 一区二区三区福利| 国产主播一区二区| 欧美激情亚洲另类| 性色av一区二区三区在线观看| 国产一区二区三区奇米久涩|