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(),这个类就有了类似函数的行为,就是一个仿函数类了

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