疯子的算法总结(二) STL Ⅰ 算法 ( algorithm )
寫在前面: 為了能夠使后續的代碼具有高效簡潔的特點,在這里講一下STL,就不用自己寫堆,寫隊列,但是做為ACMer不用學的很全面,我認為夠用就好,我只寫我用的比較多的。
什么是STL(STl內容):
容器(Container):
是一種數據結構,如list,vector,和deques ,以模板類的方法提供。為了訪問容器中的數據,可以使用由容器類輸出的迭代器;
迭代器(Iterator):
提供了訪問容器中對象的方法。例如,可以使用一對迭代器指定list或vector中的一定范圍的對象。迭代器就如同一個指針。事實上,C++的指針也是一種迭代器。但是,迭代器也可以是那些定了operator*()以及其他類似于指針的操作符地方法的類對象;
算法(Algorithm):
是用來操作容器中的數據的模板函數。例如,STL用sort()來對一個vector中的數據進行排序,用find()來搜索一個list中的對象,函數本身與他們操作的數據的結構和類型無關,因此他們可以在從簡單數組到高度復雜容器的任何數據結構上使用;
仿函數(Functor)
適配器(Adaptor)
分配器(allocator)
仿函數、適配器、與分配器用的比較少,甚至沒用過!在這里不做說明,有興趣可以自己學習一下,那個東西C++軟件工程可能用的比較多。
一、算法 ( algorithm )
如果有不理解的容器知識可以先去看看容器
<一>查找算法(9個):判斷容器中是否包含某個值
(可以去看看C++primer學學別的,但是我認為太多了沒必要)
1.count:
利用等于操作符,把標志范圍內的元素與輸入值比較,返回相等元素個數。
2.count_if:
利用輸入的操作符,對標志范圍內的元素進行操作,返回結果為true的個數。
補充:捕獲值列表,是允許我們在Lambda表達式的函數體中直接使用這些值,捕獲值列表能捕獲的值是所有在此作用域可以訪問的值,包括這個作用域里面的臨時變量,類的可訪問成員,全局變量。捕獲值的方式分兩種,一種是按值捕獲,一種是按引用捕獲。顧名思義,按值捕獲是不改變原有變量的值,按引用捕獲是可以在Lambda表達式中改變原有變量的值。
[捕獲值列表]:
1、空。沒有使用任何函數對象參數。
2、=。函數體內可以使用Lambda所在作用范圍內所有可見的局部變量(包括Lambda所在類的this),并且是值傳遞方式(相當于編譯器自動為我們按值傳遞了所有局部變量)。
3、&。函數體內可以使用Lambda所在作用范圍內所有可見的局部變量(包括Lambda所在類的this),并且是引用傳遞方式(相當于編譯器自動為我們按引用傳遞了所有局部變量)。
4、this。函數體內可以使用Lambda所在類中的成員變量。
5、a。將a按值進行傳遞。按值進行傳遞時,函數體內不能修改傳遞進來的a的拷貝,因為默認情況下函數是const的。要修改傳遞進來的a的拷貝,可以添加mutable修飾符。
6、&a。將a按引用進行傳遞。
7、a, &b。將a按值進行傳遞,b按引用進行傳遞。
8、=,&a,&b。除a和b按引用進行傳遞外,其他參數都按值進行傳遞。
9、&, a, b。除a和b按值進行傳遞外,其他參數都按引用進行傳遞。
3.equal_range:
功能類似equal,返回一對iterator,第一個表示lower_bound,第二個表示upper_bound。
4.find:
利用底層元素的等于操作符,對指定范圍內的元素與輸入值進行比較。當匹配時,結束搜索,返回該元素的一個InputIterator。
補充
InputIterator是用于輸入的Iterator
OutputIterator是用于輸出的Iterator
ForwardIterator是InputIterator,同時可以保證++運算不會使之失效
RandomIterator是ForwardIterator,同時具有+,-,+=,-=等運算及各種比較操作
5.find_end:
在指定范圍內查找"由輸入的另外一對iterator標志的第二個序列"的最后一次出現。找到則返回最后一對的第一個ForwardIterator,否則返回輸入的"另外一對"的第一個ForwardIterator。重載版本使用用戶輸入的操作符代替等于操作。
6.find_first_of:
在指定范圍內查找"由輸入的另外一對iterator標志的第二個序列"中任意一個元素的第一次出現。重載版本中使用了用戶自定義操作符。
7.find_if:
使用輸入的函數代替等于操作符執行find。返回的是迭代器,為了是大家更明白的理解,減去第一個元素的位置,就相當于得到了下標;
8.lower_bound:
返回一個ForwardIterator,指向在有序序列范圍內的可以插入指定值而不破壞容器順序的第一個位置。重載函 數使用自定義比較操作。
在一個有序的范圍內時間復雜度為log2n,普遍適用于二分算法。
跟3.equal_range的用法一樣不過這個返回的是first
9.upper_bound:
返回一個ForwardIterator,指向在有序序列范圍內插入value而不破壞容器順序的最后一個位置,該位置標志 一個大于value的值。重載函數使用自定義比較操作。跟3.equal_range的用法一樣不過這個返回的是second;
<二>排序和通用算法(7個):提供元素排序策略
inplace_merge:
合并兩個有序序列,結果序列覆蓋兩端范圍。重載版本使用輸入的操作進行排序。
merge:
合并兩個有序序列,存放到另一個序列。重載版本使用自定義的比較。 nth_element:
將范圍內的序列重新排序,使所有小于第n個元素的元素都出現在它前面,而大于它的都出現在后面。重載版本使用自定義的比較操作。
partial_sort:
對序列做部分排序,被排序元素個數正好可以被放到范圍內。重載版本使用自定義的比較操作。
partial_sort_copy:
與partial_sort類似,不過將經過排序的序列復制到另一個容器。 partition:
對指定范圍內元素重新排序,使用輸入的函數,把結果為true的元素放在結果為false的元素之前。 random_shuffle:
對指定范圍內的元素隨機調整次序。重載版本輸入一個隨機數產生操作。 reverse:
將指定范圍內元素重新反序排序。 reverse_copy: 與reverse類似,不過將結果寫入另一個容器。
rotate:
將指定范圍內元素移到容器末尾,由middle指向的元素成為容器第一個元素。
rotate_copy:
與rotate類似,不過將結果寫入另一個容器。
sort:(常用,相信大家都不陌生)
以升序重新排列指定范圍內的元素。重載版本使用自定義的比較操作。
sort(首地址,第一個不合法地址(即末地址+1),cmp)//cmp可以缺省bool cmp()//可以用到結構體上 {return (); }stable_sort:
與sort類似,不過保留相等元素之間的順序關系。 stable_partition:
與partition類似,不過不保證保留容器中的相對順序。 <三>刪除和替換算法(15個) copy:
復制序列 copy_backward: 與copy相同,不過元素是以相反順序被拷貝。 iter_swap:
交換兩個ForwardIterator的值。
<三>刪除修改復制(12個):簡單操作區間元素
remove:
刪除指定范圍內所有等于指定元素的元素。注意,該函數不是真正刪除函數。內置函數不適合使用remove和 remove_if函數。
remove_copy:
將所有不匹配元素復制到一個制定容器,返回OutputIterator指向被拷貝的末元素的下一個位置。
remove_if:
刪除指定范圍內輸入操作結果為true的所有元素。
remove_copy_if:
將所有不匹配元素拷貝到一個指定容器。
replace:
將指定范圍內所有等于vold的元素都用vnew代替。
replace_copy:
與replace類似,不過將結果寫入另一個容器。
replace_if:
將指定范圍內所有操作結果為true的元素用新值代替。
replace_copy_if:
與replace_if,不過將結果寫入另一個容器。
swap:
交換存儲在兩個對象中的值。
swap_range:
將指定范圍內的元素與另一個序列元素值進行交換。
unique: (常用于離散化)
清除序列中重復元素,和remove類似,它也不能真正刪除元素。重載版本使用自定義比較操作。
unique_copy: (同上)
與unique類似,不過把結果輸出到另一個容器。
<四>排列組合算法(2個):提供計算給定集合按一定順序的所有可能排列組合
以深搜的形式實現:
next_permutation:
取出當前范圍內的排列,并重新排序為下一個排列。重載版本使用自定義的比較操作。
prev_permutation:
取出指定范圍內的序列并將它重新排序為上一個序列。如果不存在上一個序列則返回false。重載版本使用 自定義的比較操作。
//常以此方式使用,但時間復雜度N!這個。。。。 do {//操作 }while((next_permutation(首地址,第一個不合法地址)<五>生成和異變算法(3個)
fill:
將輸入值賦給標志范圍內的所有元素。
區別于memset,memset是按位賦值,只能賦每位值相同值。
memset(首地址,value,(字節數)常用sizeof()獲取)fill_n:
將輸入值賦給first到first+n范圍內的所有元素。
// 從開始以此賦值,3個5 fill_n(首地址,3,5);transform:
將輸入的操作作用與指定范圍內的每個元素,并產生一個新的序列。重載版本將操作作用在一對元素上,另外一個元素來自輸入的另外一個序列。結果輸出到指定容器。
transform (原始對象首地址, 原始對象第一個不合法地址, 輸出對象首地址, operate(操作函數)); char operate(char c)//常用轉化大小寫,以此為例子 {if (isupper(c)){return c+32;}return c; }<六>關系算法(6個)
equal:
如果兩個序列在標志范圍內元素都相等,返回true。重載版本使用輸入的操作符代替默認的等于操作符。
includes:
判斷第一個指定范圍內的所有元素是否都被第二個范圍包含,使用底層元素的<操作符,成功返回true。重載版本使用用戶輸入的函數。
max:(很多人問我,這不是cmath嗎,呃。。。。。不是)
返回兩個元素中較大一個。重載版本使用自定義比較操作。
max_element:
返回一個ForwardIterator,指出序列中最大的元素。重載版本使用自定義比較操作。
max_element(a, a+6) 返回一個最大值位置指針min:
返回兩個元素中較小一個。重載版本使用自定義比較操作。
min(3,5)的值是5;min_element:
返回一個ForwardIterator,指出序列中最小的元素。重載版本使用自定義比較操作。
<七>集合算法(4個)
set_union:
構造一個有序序列,包含兩個序列中所有的不重復元素。重載版本使用自定義的比較操作。
set_intersection:
構造一個有序序列,其中元素在兩個序列中都存在。重載版本使用自定義的比較操作。
set_difference:
構造一個有序序列,該序列僅保留第一個序列中存在的而第二個中不存在的元素。重載版本使用自定義的比較操作。
set_symmetric_difference:
<八>堆算法(4個)
make_heap:
把指定范圍內的元素生成一個堆。重載版本使用自定義比較操作。pop_heap:
并不真正把最大元素從堆中彈出,而是重新排序堆。它把first和last-1交換,然后重新生成一個堆。可使用容器的back來訪問被"彈出"的元素或者使用pop_back進行真正的刪除。重載版本使用自定義的比較操作。
push_heap:
假設first到last-1是一個有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。在指向該函數前,必須先把元素插入容器后。重載版本使用指定的比較操作。
sort_heap:
對指定范圍內的序列重新排序,它假設該序列是個有序堆。重載版本使用自定義比較操作。
總結
以上是生活随笔為你收集整理的疯子的算法总结(二) STL Ⅰ 算法 ( algorithm )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 崩坏3试用角色用不了
- 下一篇: 电脑主板重要吗