stl算法

c++ STL algorithm 列表- -

查這些東西最好的當然是msdn,網絡msdn無疑最佳選擇

http://msdn.microsoft.com/zh-cn/library/vstudio/c37ebd05(v=vs.100).aspx

1. 查找算法 (13)   爲判斷容器中是否包含某一個值提供
adjacent_find() :一, adjacent_find(vec.begin(), vec.end()),在給定範圍[first, last)內,查找第一對相鄰的重複元素,如果找到則返回第一個元素的iterator,否則返回last;二,adjacent_find(vec.begin(), vec.end(), fun),使用函數體進行查找非線性,並且需要排過序,時間複雜度都是對數區間的

binary_search(),二分搜索,必須在有序空間,查找最快,三個參數:vec.begin(), vec.end(), 查找字符。返回值爲true或者false

lower_bound(),必須在排序,返回>=對象的第一個位置
upper_bound(),必須排序,返回>=對象的第一個位置

equal_range()必須排序,返回由lower_boundupper_bound返回值構成的pair,也就是所有等價元素區間(first是lower求出來的指針,second是upper的指針)


以下都是線性查找的

count():計算對象區間中的數目
count_if(),這個_if就像把adjacent_find()的兩種形式分拆成兩個函數一樣

find(Characters.begin(), Characters.end(), '1'); 在Characters的固定區段,查找‘1’返回iterator。

也可以查找“ab”等字符串

find_end(v1.begin(), v1.end(), v2.begin(), v2.end()) ,
在一個序列中搜索出最後一個與另一序列匹配的子序列。有如下兩個函數原型,
在迭代器區間[first1, last1)中搜索出與迭代器區間[first2, last2)元素匹配的子序列,返回首元素的迭代器或last1
find_first_of()
find_first_of() 查找第一個與value中的某值相等的字符
find_first_not_of() 查找第一個與value中的所有值都不相等的字符

find_last_of() 查找最後一個與value中的某值相等的字符

find_last_not_of() 查找最後一個與value中的所有值都不相等的字符

rfind() 查找最後一個與value相等的字符(逆向查找)

find_if(coll.begin(), coll.end(), isPrime);在coll中查找第一個滿足isprime函數爲true的

search(v1.begin(),v1.end(),v2.begin(),v2.end())但是search能夠在一個區段找另一段的子序列,返回值爲iterator
search_n(ivect.begin(), ivect.end(), 4, 8)能否在ivect找到4個8;或者result2 = search_n (v1.begin( ), v1.end( ), 3, 5, one_half ),能否在ivect找到3個5經過one_half運算完序列的函數

2. 排序(sorting)和通用(ordering)算法(14)

提供元素的排序策略。
其中stable算法保證相等元素的原來順序不變。
inplace_merge(v1.begin(),break1,v1.end())合併v1,break區段和break,v2區段兩個區段的大小;inplace_merge (v2.begin(),break2,v2.end(), greater<int>()),默認是從小到大,否則加入greater函數比較;inplace_merge( v3.begin(), break3, v3.end(), mod_lesser);mod_lesser是自定義函數,絕對值比較大小。(在一個容器內
merge(v1.begin(),v1.begin(),v1.begin(),v2.end(),v1.begin()),將有序序列v1,v2合併到一起,從小到大,其中,後面加函數的性質和inplace_merge一樣
nth_element(a,a+n,a+9)作用爲求第n小的元素。這個函數的第一功能是對a排序,然後返回第a+n位置的元素的指針。當然後面也可以加比較函數
partial_sort(v1.begin(),v1.begin() + 4,v1.end(), greater<int>()),排序v1的部分,前4個,可以有自定義的比較函數
partial_sort_copy(list1.begin(), list1.end(),v1.begin(), v1.begin() + 3)把v1的最小的三個數放在list1前3的位置(覆蓋的方法),如果改成partial_sort_copy(list1.begin(), list1.end(),v1.begin()+1, v1.begin() + 4)),就是把v1的第二到的第四的三個數放在list1第二到第四的位置,也是覆蓋的方法

partition ( v1.begin( ), v1.end( ), greater5 );將greater5爲true的元素分到前面,返回第一個爲false的iterator指針,其是採用兩個指針前後交換的形式,從頭上找到第一個爲false的和尾上第一個爲true的元素交換,移動效率超高,不過是非穩定排序

random_shuffle(vi.begin(),vi.end()),亂序排列vi,random_shuffle要求容器支持random iterator,也就是隨機訪問。但list只支持順序訪問,所以沒法應用於random_shuffle上
sort(v1.begin( ), v1.end( ))對vi進行排序,可以加仿函數或者greator<char >填入第三個參數的位置
stable_sort(),內部用的是歸併排序,穩定排序
stable_partition(),partition的穩定版本

reverse()倒序

reverse_copy(v1.begin( ), v1.end( ), v2.begin( )),將v1的倒序後放入到v2中,其中v1不變
rotate(d1.begin ( ) , d1.begin ( ) + 3, d1.end ( )),講d1的前三個元素像循環一樣放入到d1最後

rotate_copy(),v1本身不變,講rotate的結果放入的v2中


Effective STL對如何選擇排序函數總結的很好:

8.1 若需對vector, string, deque, 或array容器進行全排序,你可選擇sort或stable_sort;

8.2 若只需對vector, string, deque, 或array容器中取得top n的元素,部分排序partial_sort是首選.

8.3 若對於vector, string, deque, 或array容器,你需要找到第n個位置的元素或者你需要得到top n且不關係top n中的內部 順序,nth_element是最 理想的;

8.4 若你需要從標準序列容器或者array中把滿足某個條件 或者不滿足某個條件的元素分開,你最好使用partition或stable_partition;

8.5 若使用的list容器,你可以直接使用partition和stable_partition算法,你可以使用list::sort代替sort和stable_sort排 序。


3. 刪除和替換算法(15)
copy( v1.begin( ), v1.begin( ) + 3, v2.begin( ) + 4 );v1中前三個元素放入到v2的第五個元素的位置開始的三個地方(覆蓋)
copy_backwards(v2.begin( )+4, v2.begin( ) + 9, v2.begin( ) + 9 ),v1中第四個到第七個元素放入到以v2的第9個元素的位置結束的4個地方(覆蓋)
iter_swap(),交換兩個地址的數據,無論是pair還是個單個value
remove( v1.begin( ), v1.end( ), 7 ),刪除v1中值等於7的元素,並返回刪除前7下一個元素的指針
remove_copy(v1.begin( ), v1.end( ), v2.begin( ), 7),原v1不變,v2開始是v1刪除7後的餘下的序列,返回值是v2最後的iterator指針
remove_if(v1.begin().v1.end(),fun),滿足函數條件的就刪除

remove_copy_if ( v1.begin( ), v1.end( ), v2.begin( ), greater6 ),不滿足函數條件的就複製到v2中,是remove_copy的函數版本
replace (v1.begin( ), v1.end( ), 7 , 700),vi中數值爲7的全部替換成700
replace_copy(),本身不變,v2中的v1的7全部替換成700,返回值爲v2最後值的iterator(不是v2.end(),比其多1)
replace_if ( v1.begin( ), v1.end( ), greater6 , 70),滿足函數條件--大於7條件的就替換
replace_copy_if(),在replace_copy的基礎上改成在函數條件下
swap( v1, v2 );交換v1,v2整體
swap_ranges ( v1.begin ( ) , v1.begin ( )+N , d1.begin ( ) );將v1中n個元素的值,與對應的d1中n個元素對換,其他不變,如果d1中沒有n個元素,那麼v1中將會有n-b個隨機值(b是d1中元素的個數),並且d1中只有b個元素,就是v1的前幾個
unique(v1.begin ( ) , v1.end ( )),刪除v1中不與其他元素相同的元素
unique_copy(),原有v1不變,刪除v1中不與其他元素相同的元素到v2起始的地址中

4. 排列組合算法(2)提供計算給定集合按一定順序的所有可能的排列組合。
next_permutation(),其實也應該算排序算法,從大到小排列(具體怎麼標記的過程,在研究stl源碼的時候再深入)

int main(){
 int a[] = {3,1,2};
do{
     cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
 while (next_permutation(a,a+3));
 return 0;
}

prev_permutation()

5. 算術算法(4)
accumulate()尋找相鄰相等或者滿足函數的,返回值爲相等第一個iterator指針
partial_sum()
inner_product()
adjacent_difference()

6. 生成和異變算法(6)
fill()下面這兩個都簡單
fill_n()
for_each()循環遍歷,將每個數運算一遍指定函數,並對運算完的結果求和,得到返回值
generate()
generate_n(IntVec.begin(),9,IntSequence(1)),generate_n通過給定函數對象給指定區間中的指定數目的元素賦值,並且返回下一個未賦值的對象位置,第三個參數很奇怪,可以填入函數,可以填入類的實例,也可以填入類名(後兩者如果函數中重載了操作符“()”,除了第一次以後的每次都會進入到操作符裏去,而且具有繼承性)
transform (first.begin(), first.end(), second.begin(), op_increase); //將first中的元素按照op_increase函數運算之後寫入到second之中

7. 關係算法(7)
equal(v1.begin( ), v1.end( ), v3.begin( )),驗證是v1中的元素是否和v3的相等(長度以v1的爲準),可以加入函數,那就是v中value經過函數運算了之後是否和v3的相等,相等返回值爲true,不相等,返回值爲0。
includes ( v1a.begin ( ) , v1a.end ( ) ,v1b.begin ( ) , v1b.end ( ) ),看v1a中是否包含v1b,或者v1中都滿足其的所有元素與v2對應的元素爲參的函數爲真
lexicographical_compare (v1.begin( ), v1.end( ),L1.begin( ), L1.end( ) ),v1的元素長於v2,則爲真,否則爲false
max(),返回v1,v2中最大的,相等就返回第一個

注意vc6的庫中不支持這個函數
max_element(),求區段中最大的(具體怎麼算最大,有待考證),支持自定義函數

min
min_element()同上
results1 = mismatch (v1.begin( ), v1.end( ), L1.begin( ));比較v1v2的元素是否相等,不相等返回最開始不相等的iterator,first是v1的iterator,second是v2的
make_heap(),堆排序
pop_heap()彈出最大的
push_heap()壓入相應的位置,排序
sort_heap(),堆排序

8. 集合算法(4)set和multiset中的四個算法

set_union()       合併2個集合,並剔除相同的元素,並支持自定義函數
set_intersection()   取交集
set_difference()      取第一個集合減去第二個集合
set_symmetric_difference()   取只在一個集合中存在的元素集合

9. 堆算法(4)heap中的四個算法

note:

參數傳遞方式:by value 和by reference:一個是通過實參和形參形式,安全,一個是通過地址傳遞方式,能夠實現雙向傳遞

pair,stl中文譯爲對組,可以將兩個值視爲一個單元。對於map和multimap,就是用pairs來管理value/key的成對元素。任何函數需要回傳兩個值,也需要pair

#include <utility> 
#include <stdio.h>
using namespace std;
int main() 
{ 
    pair<char, int> c1(L'x', 3); 
    printf("[%c, %d]\n", c1.first, c1.second); 
	
    c1 = make_pair(L'y', 4); 
    printf("[{%c}, {%d}]\n", c1.first, c1.second); 
    return (0); 
} 

// map::equal_elements
#include <iostream>
#include <map>
using namespace std;
int main ()
{
 map<char,int> mymap;
 pair<map<char,int>::iterator,map<char,int>::iterator> ret;
 mymap['a']=10; mymap['b']=20; mymap['c']=30; 
ret = mymap.equal_range('b'); 
cout << "lower bound points to: ";
 cout << ret.first->first << " => " << ret.first->second << endl; 
cout << "upper bound points to: ";
 cout << ret.second->first << " => " << ret.second->second << endl; return 0;
}

仿函數(functor),就是使一個類的使用看上去象一個函數。其實現就是類中實現一個operator(),這個類就有了類似函數的行爲,就是一個仿函數類了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章