STL向导阅读④-算法

来源:互联网 发布:甬温线动车事故 知乎 编辑:程序博客网 时间:2024/06/15 09:07

#include <algorithm>

算法

常用版本

描述

返回Type

std::find()

find(_InIt _Fisrt,_InIt _Last,
_Ty& _Val);

从两个迭代器指定的范围中查找指定值

引用被查找的值的iterator或end()

std::find_if()

find_if(_InIt _Fisrt,_InIt _Last, _CallBack);

从两个迭代器指定的范围中查找与回调谓词匹配的实例

与谓词匹配的实例的iterator或end()

std::find_if_not()

find_if_not(_InIt _Fisrt,_InIt _Last,_Func _CallBack);

从迭代器范围中返回第一个不符合谓词的元素

第一个不符合谓词的元素的iterator或end()

std::count()

count(_InIt _First,_InIt _Last,
_Ty& _Val);

求得一个元素序列中与第三个参数相符的元素的个数

与第三个参数匹配的元素的int个数

std::count_if()

count_if(_InIt _First,_InIt _Last, _CallBack);

求得一个序列中与谓词匹配的元素的个数

符合条件元素的int个数

std::generate()

generate(_FwdIt _First,_FwdIt _Last, _CallBack);

通过特定值填充一个迭代器范围

void

std::max()

max(_Left,_Right /*,Predicate*/);

通过operator<或用户提供的二元谓词比较任意类型的两个元素

返回较大的一个元素的const引用

std::min()

min(_Left,_Right /*,Predicate*/);

通过operator<或用户提供的二元谓词比较任意类型的两个元素

较小的一个元素的const引用

std::max_element()

max_element(_FwdIt _First,_FwdIt _Last /*,_Pred*/);

从一组任意类型的元素元素序列中查找"最大"的一个

引用"最大”的元素的iterator

std::min_element()

min_element(_FwdIt _First,_FwdIt _Last /*,_Pred*/);

从一组任意类型的元素元素序列中查找"最小"的一个

引用"最小"的元素的iterator

adjacent_find()

adjacent_find(_FwdIt _First, _FwdIt _Last/*,_Pred*/);

从一组任意类型的元素序列中查找有重复的元素

引用重复的第一个元素的iterator或者end()

std::all_of()

all_of(_InIt _First,_InIt _Last,Pr _Pred);

当一组元素序列全部与谓词匹配时返回true否则返回false

bool

std::any_of()

any_of(_InIt _First,_InIt _Last,_Pr _Pred);

当一组元素序列中任意一个元素与谓词匹配时返回true否则返回false

bool

std::none_of()

none_of(_InIt _First,_InIt _Last,_Pr _Pred);

当一组元素序列全部都不与谓词匹配时返回true否则返回false

bool

std::for_each()

for_each(_InIt _First,_InIt _Last,_CallBack);

对指定范围内的所有元素执行一次_CallBack

_CallBackl类型


std::transform()

transform(_InIt_SrcFirst,_InIt _SrcLast,_OutIt_DestBegin,
_CallBack);

对指定范围的元素执行回调后生成新的元素,然后将这些新元素保存在第三个参数指定的目标范围中

引用Dest范围的past-the-end的_OutputIterator


-

transform(_InIt _First1,_InIt _Last,_InIt _First2,_OutIt _DestBegin,_CallBack); 

对两个指定序列的元素调用二元谓词,并将结果存入到第四个参数指定的容器中

引用Dest范围的past-the-end的_OutputIterator


std::equal()

equal(_InIt _First1,_InIt _Last1,_InIt _First2 /*,_Pred*/);

对两个不同类型的容器比较对应位置的值,当全部相等或者全部符合谓词时返回true否则返回false

 

bool



std::copy()

 

copy(_InIt _SrcBegin,_InIt _SrcEnd,_OutIt _DestBegin);

将一个序列的元素复制到另一个序列中,Src范围与Dest范围不能相同,但可以重叠,std::copy不会向目标序列中插入元素,而会直接修改元素,使用前必须配合_Dest序列的resize()函数给Dest序列重分配足够的空间

 

引用Dest范围
past_the_end的_OutputIterator

std::copy_backward()

copy_backward(_InIt _SrcBegin,_InIt _SrcEnd,_OutIt _DestEnd);

将Src范围的元素反向复制到Dest范围中,也就是从Src范围最后一个元素开始复制,将这个元素放在Dest范围的最后一个位置,然后再每一次复制后反向移动.第三个参数应该是_DestEnd而不是_DestBegin

引用Dest范围的_Begin()的_OutputIterator



 

std::copy_if

 

 

copy_if(_InIt _SrcBegin,_InIt _SrcEnd,_OutIt _DestBegin,
_Pr _Pred);

对一个序列中每个准备复制的元素执行一次_Callback,如果返回值为true,那么执行copy操作,否则不执行;返回了Dest范围中最后一个复制的元素的后一个位置,这是为了配合past_the_end来删除多余的元素:复制完成后使用_Dest.erase(_CopyEndIt,past_the_end);来删除Dest范围多余的元素位置

 

 

返回引用Dest范围的最后一个复制的元素的后一个位置的_OutputIterator

std::copy_n()

copy_n(_InIt _SrcBegin,_Ty _Cnt,_OutIt _DestBegin);

从Src范围复制_Cnt个元素到Dest范围,第二个参数是一个指定要复制的元素个数的整数

返回引用Dest范围的past_the_end



 

std::partition_copy()

 

 

 

partition_copy(_InIt _SrcBegin,_InIt _SrcEnd,_OutIt _Dest1,_OutIt _Dest2,_Pr _Pred);

对一个序列的元素进行依据谓词返回的结果进行划分复制,首先对Src序列中的每一个元素执行一次谓词,如果返回true,那么将这个元素复制到_Dest1,如果返回false,复制到_Dest2,复制之前需要使用resize()重置Dest的空间;算法返回一个打包_Dest1和_Dest2的one_past_the_last_copied的std::pair,利用这个pair可以删除多分配的空间

 

 

打包引用_Dest1和_Dest2的one_past_the_last_copied的_OutputIterator的std::pair


std::move()

 

move(_InIt _SrcBegin,_InIt _SrcEnd,_OutIt _DestBegin);

需要给元素提供移动赋值运算符,将Src序列的元素通过移动赋值运算符移动到Dest序列,在移动操作中,SrcObject被重置了,因为DstObject接管了SrcObject资源的所有权,
这意味着在move操作过后Src序列中的对象不能再使用

返回Dest范围的引用past_the_end的_OutputIterator

Std::move_backward()

move_backward(_InIt _SrcBegin,
_InIt _SrcEnd,_OutIt _DstEnd)

使用了和std::move()相同的移动机制,但是按照从最后一个元素向第一个元素的顺序进行移动

返回Dest范围的引用_Begin()的_OutputIterator

std::replace()

replace(_FwdIt _First,_FwdIt _Last,const _Ty& _OldVal,const _Ty& _NewVal);

这个算法将一个范围中的匹配某个值的元素替换为第三个参数指定的新值

void

std::replace_if()

replace_if(_FwdIt _First,_FwdIt _Last,_Pr _Pred,
const _Ty& _NewVal);

这个算法将一个范围中的匹配某个谓词的元素替换为第三个参数指定的新值

void

 

std::remove()

 

remove(_FwdIt _First,_FwdIt _Last,const _Ty& _Val); 

这个算法并不是将序列中与_Val匹配的元素直接删除,而是将它们移动到容器的末端,然后返回引用第一个被移除的元素的iterator,可以利用这个iterator和end()将被移除的元素彻底擦除

 

返回引用第一个被移除的元素的_FwdIterator

 

std::remove_if()

 

remove_if(_FwdIt _First,_FwdIt _Last,_Pr _Pred);

这个算法并不是将序列中与谓词匹配的元素直接删除,而是将它们移动到容器的末端,然后返回引用第一个被移除的元素的iterator,可以利用这个iterator和end()将被移除的元素彻底擦除

 

返回引用第一个被移除的元素的_FwdIterator



std::unique()

 

 

unique(_FwdIt _First,_FwdIt _Last /*,_Pr _Pred)*/;

std::unique算法是特殊的std::remove算法,和后者一样,std::unique并不是直接将重复的元素删除,而是将它们全部移动到容器的尾端,然后返回引用第一个被移除的元素的iterator,可以利用这个iterator和end()将被移除的元素彻底擦除

 

 

返回引用第一个被移除的元素的_FwdIterator

std::unique_copy

unique(_FwdIt _SrcBegin,_FwdIt _SrcEnd,_OutIt _DestBegin  /*,_Pr _Pred*/);

std::unique()的基本形式是就地操作数据,std::unique_copy则是将操作的结果复制到Dest范围中

返回引用Dest范围的元素的_OutputIterator

std::reverse()

reverse(_BidIt _First,_BidIt _Last);

将范围中的第一个元素和最后一个元素交换,第二个元素和倒数第二个元素交换,依此类推

Void


std::reverse_copy()

reverse_copy(_BidIt _SrcBegin,_BidIt _SrcEnd,
_OutIt _DestBegin);

std::reverse是就地操作数据,std::reverse_copy将结果复制到Dest范围中

返回引用Dest范围的元素的_OutputIterator

std::sort()

sort(_RanIt _First,_RanIt _Last /*,_Pr _Pred*/);

将范围中的元素按operator<或_CallBack进行排序

Void



std::merge()

 

merge(_InIt _SrcBegin1,_InIt _SrcEnd1,_InIt _SrcBegin2,_InIt _SrcEnd2,_OutIt _DestBegin, 
/*,_Pr _Prd*/);

将两个排好序的Src序列合并成一个元素序列,然后将结果复制到Dest序列中,并且依然保持排序的顺序,结果是一个包含两个Src序列的所有元素的有序序列,注意一定要使用两个排好序的序列进行merge操作

 

引用Dest序列的past_the_end的_OutputIterator

std::is_sorted()

sort(_FwdIt _First,_FwdIt _Last /*,_Pr _Pred*/);

验证一个序列是否是有序序列.如果是,返回true,否则返回false

bool

 

std:random_shuffle()

 

random_shuffle(_RanIt _First,_RanIt _Last /*,_Fn& _Func*/

将一个序列的顺序打乱,这个算法适用于洗牌之类的任务,对一个版本默认使用标准C库的rand()函数,第二个版本需要提供一个随机数生成器, 以适应不同问题领域的随机性

 

void

 

 

 

 

 

集合算法

 

 

std::includes()

includes(_InIt _First1,_InIt _Last1,_InIt _First2,_InIt _Last2 /*,_Pr _Pred*/);


验证第二个序列是否是第一个序列的子集,注意不是真子集,而是子集,如果是返回true,否则返回false


bool

 

 

 

std::set_union()

 

set_union(_InIt _SrcBegin1,
_InIt _SrcEnd1,
_InIt _SrcBegin2,
_InIt _SrcEnd2,
_OutIt _DestBegin 
/*,_Pr _Pred*/);

计算两个有序序列的并集,然后将并集的结果存入第四个参数指定的Dest序列中,注意在计算前必须给Dest容器分配足够的空间,因为Dest范围最大是_Src1和_Src2的size()和,所以在进行合并后有可能会留下一些空间,set_union算法返回一个引用Dest范围中最后一个被添加进去的元素的后一个位置的iterator,利用它可以将Dest中多余的空间删除

 

返回一个引用Dest范围中最后一个被添加进去的元素的后一个位置的_OutputIterator

 




std::set_intersection()

set_intersection(

_InIt _SrcBegin1,
_InIt _SrcEnd1,
_InIt _SrcBegin2,
_InIt _SrcEnd2,
_OutIt _DestBegin 
/*,_Pr _Pred*/);

计算两个有序序列的交集,然后将交集的结果存入第四个参数指定的Dest序列中,注意在计算前必须给Dest容器分配足够的空间,因为Dest范围最大是两个_Src范围的size的最大值,所以在进行取交集后有可能会留下一些空间,set_union算法返回一个引用Dest范围中最后一个被添加进去的元素的后一个位置的iterator,利用它可以将Dest中多余的空间删除

 

返回一个引用Dest范围中最后一个被添加进去的元素的后一个位置的_OutputIterator

 

 

 

 

std ::set_difference()

 

set_difference(

_InIt _SrcBegin1,
_InIt _SrcEnd1,
_InIt _SrcBegin2,
_InIt _SrcEnd2,
_OutIt _DestBegin 
/*,_Pr _Pred*/);

计算两个有序序列的集合差,(集合差:所有存在于第一个集合,但是不存在与第二个集合中的所有元素),然后将求集合差的结果存入第四个参数指定的Dest序列中,注意在计算前必须给Dest容器分配足够的空间,因为Dest范围最大是两个_Src范围的size的最大值,所以在进行取交集后有可能会留下一些空间,set_union算法返回一个引用Dest范围中最后一个被添加进去的元素的后一个位置的iterator,利用它可以将Dest中多余的空间删除

 

返回一个引用Dest范围中最后一个被添加进去的元素的后一个位置的_OutputIterator

 




std::set_symmetric_difference()

set_symmetric_difference(

_InIt _SrcBegin1,
_InIt _SrcEnd1,
_InIt _SrcBegin2,
_InIt _SrcEnd2,
_OutIt _DestBegin 
/*,_Pr _Pred*/);

计算两个有序序列的对称集合差,(对称集合差:所有存在于某一个集合,但是不存在与第二个集合中的元素),然后将求对称集合差的结果存入第四个参数指定的Dest序列中,注意在计算前必须给Dest容器分配足够的空间,因为Dest范围最大是_Src1和_Src2的size()和,所以在进行取交集后有可能会留下一些空间,set_union算法返回一个引用Dest范围中最后一个被添加进去的元素的后一个位置的iterator,利用它可以将Dest中多余的空间删除

 

 

返回一个引用Dest范围中最后一个被添加进去的元素的后一个位置的_OutputIterator

 

Warning: 务必要确保Dest范围足够大,足以保存操作的结果.

对于set_union()和set_symmetric_difference(),结果大小的上限是两个输入范围的总和.

对于set_intersection()和set_difference(),结果大小的上限是两个输入范围大小中的最大值.

 

 

#include <numeric>

算法

常用版本

描述

返回Type

std::accumulate()

accumulate(_InIt _First,_InIt _Last,_Ty& _Val);

对一个由两个迭代器指定的序列的元素求和

返回一个指定的序列的求和的值

 

-

accumulate(_InIt _First,_InIt _Last,Ty& _Val,

_Func _CallBack);

 

对一个由两个迭代器指定的序列进行调用者指定的操作

返回对一个序列执行指定操作的值

std::iota()

iota(_FwdIt _First,_FwdIt _Last,_Ty& _Val);

生成一个指定范围内的序列值,由第三个实参指定的值开始使用operator++递增,调用此算法之前必须要指定容器的size()

void

  

算法复杂度大O表示法

算法复杂度

大O表示法

说明

事例算法

常数

O(1)

运行时间与输入量无关

访问数组中的某个元素

对数

O(log n)

运行时间是输入量以2为底的对数的函数

使用二分法查找有序列表中的元素

线性

O(n)

运行时间与输入量成正比

未排序列表中查找元素

线性对数

O(n log n)

运行时间是输入量的对数函数的线性倍的函数

归并排序

二次方

O(n²)

运行时间是输入量的平方的函数

较慢的排序算法,如选择排序算法

 

                                               STL所有算法70个分界线                                           

  STL算法部分主要由头文件<algorithm>,<numeric>,<functional>组成。要使用 STL中的算法函数必须包含头文件<algorithm>,对于数值算法须包含<numeric><functional>中则定义了一些模板类,用来声明函数对象。
    STL
中算法大致分为四类:
        1
、非可变序列算法:指不直接修改其所操作的容器内容的算法。
        2
、可变序列算法:指可以修改它们所操作的容器内容的算法。
        3
、排序算法:包括对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
        4
、数值算法:对容器内容进行数值计算。

    以下对所有算法进行细致分类并标明功能:
    <
>查找算法(13):判断容器中是否包含某个值
    adjacent_find:           
iterator对标识元素范围内,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的ForwardIterator。否则返回last。重载版本使用输入的二元操作符代替相等的判断。
   binary_search:           
在有序序列中查找value,找到返回true。重载的版本实用指定的比较函数对象或函数指针来判断相等。
   count:                   
利用等于操作符,把标志范围内的元素与输入值比较,返回相等元素个数。
   count_if:                
利用输入的操作符,对标志范围内的元素进行操作,返回结果为true的个数。
   equal_range:             
功能类似equal,返回一对iterator,第一个表示lower_bound,第二个表示upper_bound
   find:                    
利用底层元素的等于操作符,对指定范围内的元素与输入值进行比较。当匹配时,结束搜索,返回该元素的一个InputIterator
    find_end:                
在指定范围内查找"由输入的另外一对iterator标志的第二个序列"的最后一次出现。找到则返回最后一对的第一个ForwardIterator,否则返回输入的"另外一对"的第一个ForwardIterator。重载版本使用用户输入的操作符代替等于操作。
   find_first_of:           
在指定范围内查找"由输入的另外一对iterator标志的第二个序列"中任意一个元素的第一次出现。重载版本中使用了用户自定义操作符。
    find_if:                 
使用输入的函数代替等于操作符执行find
   lower_bound:             
返回一个ForwardIterator,指向在有序序列范围内的可以插入指定值而不破坏容器顺序的第一个位置。重载函数使用自定义比较操作。
   upper_bound:             
返回一个ForwardIterator,指向在有序序列范围内插入value而不破坏容器顺序的最后一个位置,该位置标志一个大于value的值。重载函数使用自定义比较操作。
   search:                  
给出两个范围,返回一个ForwardIterator,查找成功指向第一个范围内第一次出现子序列(第二个范围)的位置,查找失败指向last1。重载版本使用自定义的比较操作。
   search_n:                
在指定范围内查找val出现n次的子序列。重载版本使用自定义的比较操作。

    <>排序和通用算法(14):提供元素排序策略
   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:                    
以升序重新排列指定范围内的元素。重载版本使用自定义的比较操作。
   stable_sort:             
sort类似,不过保留相等元素之间的顺序关系。
   stable_partition:        
partition类似,不过不保证保留容器中的相对顺序。

    <>删除和替换算法(15)
   copy:                    
复制序列
   copy_backward:           
copy相同,不过元素是以相反顺序被拷贝。
   iter_swap:               
交换两个ForwardIterator的值。
    remove:                  
删除指定范围内所有等于指定元素的元素。注意,该函数不是真正删除函数。内置函数不适合使用removeremove_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。重载版本使用自定义的比较操作。

    <>算术算法(4)
   accumulate:              iterator
对标识的序列段元素之和,加到一个由val指定的初始值上。重载版本不再做加法,而是传进来的二元操作符被应用到元素上。
   partial_sum:             
创建一个新序列,其中每个元素值代表指定范围内该位置前所有元素之和。重载版本使用自定义操作代替加法。
   inner_product:           
对两个序列做内积(对应元素相乘,再求和)并将内积加到一个输入的初始值上。重载版本使用用户定义的操作。
    adjacent_difference:     
创建一个新序列,新序列中每个新值代表当前元素与上一个元素的差。重载版本用指定二元操作计算相邻元素的差。

    <>生成和异变算法(6)
   fill:                    
将输入值赋给标志范围内的所有元素。
   fill_n:                  
将输入值赋给firstfirst+n范围内的所有元素。
   for_each:                
用指定函数依次对指定范围内所有元素进行迭代访问,返回所指定的函数类型。该函数不得修改序列中的元素。
   generate:                
连续调用输入的函数来填充指定的范围。
    generate_n:              
generate函数类似,填充从指定iterator开始的n个元素。
   transform:               
将输入的操作作用与指定范围内的每个元素,并产生一个新的序列。重载版本将操作作用在一对元素上,另外一个元素来自输入的另外一个序列。结果输出到指定容器。

    <>关系算法(8)
   equal:                   
如果两个序列在标志范围内元素都相等,返回true。重载版本使用输入的操作符代替默认的等于操作符。
   includes:                
判断第一个指定范围内的所有元素是否都被第二个范围包含,使用底层元素的<操作符,成功返回true。重载版本使用用户输入的函数。
    lexicographical_compare: 
比较两个序列。重载版本使用用户自定义比较操作。
   max:                     
返回两个元素中较大一个。重载版本使用自定义比较操作。
   max_element:             
返回一个ForwardIterator,指出序列中最大的元素。重载版本使用自定义比较操作。
   min:                     
返回两个元素中较小一个。重载版本使用自定义比较操作。
   min_element:             
返回一个ForwardIterator,指出序列中最小的元素。重载版本使用自定义比较操作。
   mismatch:                
并行比较两个序列,指出第一个不匹配的位置,返回一对iterator,标志第一个不匹配元素位置。如果都匹配,返回每个容器的last。重载版本使用自定义的比较操作。

    <>集合算法(4)
   set_union:               
构造一个有序序列,包含两个序列中所有的不重复元素。重载版本使用自定义的比较操作。
   set_intersection:        
构造一个有序序列,其中元素在两个序列中都存在。重载版本使用自定义的比较操作。
   set_difference:          
构造一个有序序列,该序列仅保留第一个序列中存在的而第二个中不存在的元素。重载版本使用自定义的比较操作。
    set_symmetric_difference:
构造一个有序序列,该序列取两个序列的对称差集(并集-交集)
 
    <
>堆算法(4)
   make_heap:               
把指定范围内的元素生成一个堆。重载版本使用自定义比较操作。
   pop_heap:                
并不真正把最大元素从堆中弹出,而是重新排序堆。它把firstlast-1交换,然后重新生成一个堆。可使用容器的back来访问被"弹出"的元素或者使用pop_back进行真正的删除。重载版本使用自定义的比较操作。
   push_heap:               
假设firstlast-1是一个有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。在指向该函数前,必须先把元素插入容器后。重载版本使用指定的比较操作。
   sort_heap:               
对指定范围内的序列重新排序,它假设该序列是个有序堆。重载版本使用自定义比较操作。

 

          

0 0