算法参数说明
/***********************标准库算法参数说明*******************/beg & end //表示元素范围的迭代器。几乎所有算法都对一个由beg和end表示的序列进行操作。beg2 //是表示第二个输入序列开始位置的迭代器。end2 //表示第二个序列的末尾位置(如果有的话)。如果没有end2,则假定beg2表示的序列//与beg和end表示的序列一样大。beg和beg2的类型不必匹配,//但是,必须保证对两个序列中的元素都可以执行特定操作或调用给定的可调用对象。dest //表示目的序列的迭代器。对于给定输入序列,算法需要生成多少元素,目的序列//必须保证能保存同样多的元素。unaryPred & binaryPred //是一元和二元谓词,分别接受一个和两个参数,都是来自输入序列的元素,//两个谓词都返回可用作条件的类型。comp //是一个二元谓词,满足关联容器中对关键字序的要求unaryOp & binaryOp //是可调用对象,可分别使用来自输入序列的一个和两个实参来调用。
查找对象算法
简单查找算法
find(beg, end, val);//返回一个迭代器,指向输入序列中第一个等于 val 的元素。find_if(beg , end, unaryPred);//返回一个迭代器,指向第一个满足 unaryPred 的元素 。find_if_not(beg, end, unaryPred);//返回一个迭代器,指向第一个令unaryPred为false的元素。//上述三个算法在未找到元素时都返回 end 。count(beg, end , val);//返回一个计数器,指出val出现了多少次count_if(beg, end, unaryPred);//统计有多少个元素满足unaryPredall_of(beg, end, unaryPred); //unaryPred是否对所有元素都成功,序列空返回falseany_of(beg, end, unaryPred); //unaryPred对任意一个元素成功,序列空返回truenone_of(beg, end, unaryPred); //unaryPred对所有元素都不成功,序列空返回true
查找重复算法
在输入序列中查找重复元素,要求前向迭代器。
adjacent_find(beg, end)adjacent_find(beg, end, binaryPred);//返回指向第一对相邻重复元素的迭代器。如果序列中无相邻重复元素,则返回end。search_n(beg, end, count, val);search_n(beg, end, count, val, binaryPred);//返回一个迭代器,从此位置开始有count个相等元素。如果序列中不存在这样的子序列,则返回 end 。
查找子序列算法
除了find_first_of之外,都要求两个前向迭代器。find_first_of用输入迭代器表示第一个序列,用前向迭代器表示第二个序列。这些算法搜索子序列而不是单个元素。
search(beg1, end1, beg2, end2);search(beg1, end1, beg2, end2, binaryPred);//返回第二个输入范围(子序列)在第一个输入范围中第一次出现的位置。如果未找到子序列,则返回end1。find_end(begl, endl, beg2, end2);find_end(begl, endl, beg2, end2, binaryPred);//类似search, 但返回的是最后一次出现的位置。如果第二个输入范围为空,或者在第一//个输入范围中未找到它,则返回end1。find_first_of(beg1, end1, beg2, end2);find_first_of(beg1, end1, beg2, end2, binaryPred);//返回一个迭代器,指向第二个输入范围中任意元素在第一个范围中首次出现的位置。如果//未找到匹配元素,则返回end1。
其他只读算法
要求前两个实参都是输入迭代器。equal和mismatch算法还接受一个额外的输入迭代器,表示第二个范围的开始位置。这两个算法都提供两个重载的版本。第一个版本使用底层类型的相等运算符(==)比较元素,第二个版本则用用户指定的 unaryPred 或 binaryPred 比较元素。
for_each(beg, end, unaryOp);//对输入序列中的每个元素应用可调用对象unaryOp。unaryOp的返回值(如果有的话)被忽略。//如果迭代器允许通过解引用运算符向序列中的元素写入值,则unaryOp可能修改元素。mismatch(begl, endl, beg2);mismatch(begl, endl, beg2, binaryPred);//比较两个序列中的元素。返回一个迭代器的pair,表示两个序列中第一个不匹配的元素。//如果所有元素都匹配,则返回的pair中第一个迭代器为end1,//第二个迭代器指向beg2中偏移量等于第一个序列长度的位置。equal(beg1, end1, beg2);equal(beg1, end1, beg2, binaryPred);//确定两个序列是否相等。//如果输入序列中每个元素都与从beg2开始的序列中对应元素相等,则返回true。
二分搜索算法
这些算法都要求前向迭代器,如果我们提供随机访问迭代器 ( random-access iterator) 的话,它们的性能会好得多。从技术上讲,无论我们提供什么类型的迭代器,这些算法都会执行对数次的比较操作 。但是,当使用前向迭代器时,这些算法必须花费线性次数的迭代器操作来移动到序列中要比较的元素。
这些算法要求序列中的元素已经是有序的。它们的行为类似关联容器的同名成员。 equal_range 、 lower_bound 和 upper_bound 算法返回迭代器,指向给定元素在序列中的正确插入位置——插入后还能保持有序。如果给定元素比序列中的所有元素都大,则会返回尾后迭代器。
每个算法都提供两个版本 : 第一个版本用元素类型的小于运算符(<)来检测元素;第二个版本则使用给定的比较操作。在下列算法中, ”x 小于 y” 表示 x<y 或 comp ( x , y)成功。
lower_bound(beg, end, val);lower_bound(beg, end, val, comp);//返回一个迭代器,表示第一个小于等于val的元素,如果不存在这样的元素,则返回end。upper_bound(beg, end, val);upper_bound(beg, end, val, comp);//返回一个迭代器,表示第一个大于val的元素,如果不存在这样的元素,则返回end。equal_range(beg, end, val);equal_range(beg, end, val, comp);//返回一个pair//first成员是lower_bound返回的迭代器,//second成员是upper_bound返回的迭代器。binary_search(beg, end, val);binary_search(beg, end, val, comp);//返回一个bool值,指出序列中是否包含等于val的元素。//对于两个值x和y,当x不小于y且y也不小于x时,认为它们相等。
写容器元素算法
很多算法向给定序列中的元素写入新值。这些算法可以从不同角度加以区分:通过表示输入序列的迭代器类型来区分;或者通过是写入输入序列中元素还是写入给定目的位置来区分。
只写不读元素的算法
这些算法要求一个输出迭代器(outputiterator),表示目的位置。_n结尾的版本接受第二个实参,表示写入的元素数目,并将给定数目的元素写入到目的位置中。
fill(beg, end, val)fill_n(dest, cnt, val)generate(beg, end, Gen)generate_n(dest, cnt, Gen)//给输入序列中每个元素赋予一个新值。// 1、fill将值val赋予元素;// 2、generate执行生成器对象Gen()生成新值。生成器是一个可调用对象,// 每次调用会生成一个不同的返回值。//fill和generate都返回void。//_n版本返回一个迭代器,指向写入到输出序列的最后一个元素之后的位置。
使用输入迭代器的写算法
这些算法读取一个输入序列,将值写入到一个输出序列中。它们要求一个名为dest的输出迭代器,而表示输入范围的迭代器必须是输入迭代器。
copy(beg, end, dest)copy_if(beg, end, dest, unaryPred)copy_n(beg, n, dest)//从输入范围将元素拷贝到dest指定的目的序列。// copy拷贝所有元素,// copy_if拷贝那些满足unaryPred的元素,// copy_n拷贝前n个元素,输入序列必须有至少n个元素。move(beg, end, dest)//对输入序列中的每个元素调用std::move,将其移动到迭代器dest开始的序列中。transform(beg, end, dest, unaryOp)transform(beg, end, beg2, dest, binaryOp)//调用给定操作,并将结果写到dest中。// 第一个版本对输入范围中每个元素应用一元操作。// 第二个版本对两个输入序列中的元素应用二元操作。replace_copy(beg, end, dest, old_val, new_val)replace_copy_if(beg, end, deat, unaryPred, new_val)//将每个元素拷贝到dest, 将指定的元素替换为newval。// 第一个版本替换那些==old_val的元素。// 第二个版本替换那些满足unaryPr;d的元素。merge(begl, endl, beg2, end2, dest)merge(begl, endl, beg2, end2, dest, comp)//两个输入序列必须都是有序的。将合并后的序列写入到dest中。// 第一个版本用<运算符比较元素;// 第二个版本则使用给定比较操作。
使用前向迭代器的写算法
这些算法要求前向迭代器,由千它们是向输入序列写入元素,迭代器必须具有写入元素的权限。
iter_swap(iterl, iter2)//交换iterl和iter2所表示的元素,返回voidswap_ranges(begl, endl, beg2)//将输入范围中所有元素与beg2开始的第二个序列中所有元素进行交换。两个范围不能有重叠。// swap_ranges返回递增后的beg2, 指向最后一个交换元素之后的位置。replace(beg, end, old_val, new_val)replace_if(beg, end, unaryPred, new_val)//用new_val替换每个匹配元素。// 第一个版本使用==比较元素与old_val,// 第二个版本替换那些满足unaryPred的元素。
使用双向迭代器的算法
这些算法需要在序列中有反向移动的能力,因此它们要求双向迭代器(bidirectional iterator)。
copy_backward(beg, end, dest)move_backward(beg, end, dest)//从输入范围中拷贝或移动元素到指定目的位置。与其他算法不同,//dest是输出序列的尾后迭代器(即,目的序列恰在dest之前结束)。//输入范围中的尾元素被拷贝或移动到目的序列的尾元素,//然后是倒数第二个元素被拷贝/移动,依此类推。元素在目的序列中的顺序与在输入序列中相同。//如果范围为空,则返回值为dest,//否则,返回值表示从*beg中拷贝或移动的元素。inplace_merge(beg, mid, end)inplace_merge(beg, mid, end, comp)//将同一个序列中的两个有序子序列合并为单一的有序序列。//beg到mid间的子序列、mid到end间的子序列被合并,并被写入到原序列中。// 第一个版本使用<比较元素,// 第二个版本使用给定的比较操作,//返回void
划分与排序算法
对于序列中的元素进行排序,排序和划分算法提供了多种策略。每个排序和划分算法都提供稳定和不稳定版本。稳定算法保证保持相等元素的相对顺序。由于稳定算法会做更多工作,可能比不稳定版本慢得多并消耗更多内存 。
划分算法
一个划分算法将输入范围中的元素划分为两组。第一组包含那些满足给定谓词的元系,第二组则包含不满足谓词的元素。例如,对于一个序列中的元素,我们可以根据元素是否是奇数或者单词是否以大写字母开头等来划分它们。这些算法都要求双向迭代器。
is_yartitioned(beg, end, unaryPred)//如果所有满足谓词unaryPred的元素都在不满足unaryPred的元素之前,//则返回true。若序列为空,也返回true。partition_copy(beg, end, destl, dest2, unaryPred)//将满足unaryPred的元素拷贝到destl,并将不满足unaryPred的元素拷贝到dest2。//返回一个迭代器pair// first表示拷贝到destl的元素的末尾,// second表示拷贝到dest2的元素的末尾。//输入序列与两个目的序列都不能重叠。partition_point(beg, end, unaryPred)//输入序列必须是已经用unaryPred划分过的。//返回满足unaryPred的范围的尾后迭代器。//如果返回的迭代器不是end, 则它指向的元素及其后的元素必须都不满足unaryPred。stable_partition(beg, end, unaryPred)partition(beg, end, unaryPred)//使用unaryPred划分输入序列。//满足unaryPred的元素放置在序列开始,不满足的元素放在序列尾部。//返回一个迭代器,指向最后一个满足unaryPred的元素之后的位置,//如果所有元素都不满足unaryPred, 则返回beg。
排序算法
这些算法要求随机访问迭代器。每个排序算法都提供两个重载的版本。一个版本用元素的<运算符来比较元素,另一个版本接受一个额外参数来指定排序关系。partial_sort_copy返回一个指向目的位置的迭代器,其他排序算法都返回void。
    partial_sort和nth_element算法都只进行部分排序工作,它们常用于不需要排序整个序列的场合。由于这些算法工作量更少,它们通常比排序整个输入序列的算法更快。
sort(beg, end)stable_sort(beg, end)sort(beg, end, comp)stable_sort(beg, end, comp)//排序整个范围。is_sorted(beg, end)is_sorted(beg, end, comp)//返回一个bool值,指出整个输入序列是否有序。is_sorted_until(beg, end)is_sorted_until(beg, end, comp)//在输入序列中查找最长初始有序子序列,并返回子序列的尾后迭代器。partial_sort(beg, mid, end)partial_sort(beg, mid, end, comp)//排序mid-beg个元素。//即,如果mid-beg等于42, 则此函数将值最小的42个元素有序放在序列前42个位置。//完成后,从beg开始直至mid之前的范围中的元素就都已排好序了。//已排序范围中的元素都不会比mid后的元素更大。未排序区域中元素的顺序是未指定的。partial_sort_copy(beg, end, destBeg, destEnd)partial_sort_copy(beg, end, destBeg, destEnd, comp)//排序输入范围中的元素,并将足够多的已排序元素放到destBeg和destEnd所指示的序列中。//如果目的范围的大小>=输入范围,则排序整个输入序列并存入从destBeg开始的范围。//如果目的范围大小<输入范围,则只拷贝输入序列中与目的范围一样多的元素。//算法返回一个迭代器,指向目的范围中已排序部分的尾后迭代器。//如果目的序列的大小<=输入范围,则返回destEnd。nth_element(beg, nth, end)nth_element(beg, nth, end, comp)//参数nth必须是一个迭代器,指向输入序列中的一个元素。//执行nth_element后,此迭代器指向的元素恰好是整个序列排好序后此位置上的值。//序列中的元素会围绕nth进行划分:nth之前的元素都小于等于它,而之后的元素都大于等于它
通用重排操作
这些算法重排输入序列中元素 的顺序。前两个算法 remove 和 unique , 会重排序列 ,使得排在序列第一部分的元素满足某种标准。它们返回一个迭代器,标记子序列的末尾。其他算法 ,如 reverse 、 rotate 和 random_shuffle 都重排整个序列 。
这些算法的基本版本都进行“原址”操作,即, 在输入序列自身 内 部重排元素。 三个重排算法提供“拷贝"版本。这些_copy 版本完成相同的重排工作,但将重排后的元素写入到 一个指定目的序列中,而不是改变输入序列。这些算法要求输出迭代器来表示目的序列。
使用前向迭代器的重排算法
这些算法重排输入序列。它们要求迭代器至少是前向迭代器。
remove(beg, end, val)remove_if(beg, end, unaryPred)remove_copy(beg, end, dest, val)ramove_copy_if(beg, end, dest, unaryPred)//从序列中“删除“元素,采用的办法是用保留的元素覆盖要删除的元素。//被删除的是那些==val或满足unaryPred的元素。//返回一个迭代器,指向最后一个删除元素的尾后位置。unique(beg, end)unique(beg, end, binaryPred)unique_copy(beg, end, dest)unique_copy_if(beg, end, dest, binaryPred)//重排序列,对相邻的重复元素,通过覆盖它们来进行“删除"。//返回一个迭代器,指向不重复元素的尾后位置。//第一个版本用==确定两个元素是否相同,//第二个版本使用谓词检测相邻元素。rotate(beg, mid, end)rotate_copy(beg, mid, end, dest)//围绕mid指向的元素进行元素转动。//元素mid成为首元素,随后是mid+1到end之前的元素,再接着是beg到mid之前的元素。//返回一个迭代器,指向原来在beg位置的元素。
使用双向迭代器的重排算法
由于这些算法要反向处理输入序列,它们要求双向迭代器。
reverse(beg, end)//翻转序列中的元素。返回void,reverse_copy(beg, end, dest)//翻转序列中的元素。//返回一个迭代器,指向拷贝到目的序列的元素的尾后位置。
使用随机访问迭代器的重排算法
由于这些算法要随机重排元素,它们要求随机访问迭代器。
random_shuffle(beg, end)random_shuffle(beg, end, rand)shuffle(beg, end, Uniform_rand)//混洗输入序列中的元素。//第二个版本接受一个可调用对象参数,该对象必须接受一个正整数值,//并生成0到此值的包含区间内的一个服从均匀分布的随机整数。//shuffle的第三个参数必须满足均匀分布随机数生成器的要求。//所有版本都返回void
排列算法
排列算法生成序列的字典序排列。对于一个给定序列 , 这些算法通过重排它的一个排列来生成字典序中下一个或前一个排列 。算法返回一个 bool 值,指出是否还有下一个或前一个排列。
为了理解什么是下一个或前一个排列,考虑下面这个三字符的序列 : abc 。它有六种可能的排列: abc 、 acb 、 bac 、 bca 、cab及cba。这些排列是按字典序递增序列出的。即,abc是第一个排列,这是因为它的第一个元素小于或等于任何其他排列的首元素,并且它的第二个元素小于任何其他首元素相同的排列。类似的,acb排在下一位,原因是它以a开头,小于任何剩余排列的首元素。同理,以b开头的排列也都排在以c开头的排列之前。
对于任意给定的排列,基于单个元素的一个特定的序,我们可以获得它的前一个和下一个排列。给定排列bca, 我们知道其前一个排列为bac, 下一个排列为cab。序列abc没有前一个排列,而cba没有下一个排列。
这些算法假定序列中的元素都是唯一的,即,没有两个元素的值是一样的。
为了生成排列,必须既向前又向后处理序列,因此算法要求双向迭代器。
is_permutation{begl, endl, beg2)is_permutation{begl, endl, beg2, binaryPred)//如果第二个序列的某个排列和第一个序列具有相同数目的元素,且元素都相等,则返回true。//第一个版本用=比较元素,//第二个版本使用给定的binaryPred。next_yermutation(beg, end)next_yermutation{beg, end, comp)//如果序列已经是最后一个排列,则next_permutation将序列重排为最小的排列,并返回false。//否则,它将输入序列转换为字典序中下一个排列,并返回true。//第一个版本使用元素的<运算符比较元素,//第二个版本使用给定的比较操作。prev_permutation(beg, end)prev_permutation(beg, end, comp)//类似next_premutation, 但将序列转换为前一个排列。如果序列已经是最小的排列,//则将其重排为最大的排列,并返回false。
有序序列的集合算法
集合算法实现了有序序列上的一般集合操作。这些算法与标准库set容器不同,不要与set上的操作相混淆。这些算法提供了普通顺序容器(vector、list等)或其他序列(如输入流)上的类集合行为。
这些算法顺序处理元素,因此要求输入迭代器。他们还接受一个表示目的序列的输出迭代器,唯一的例外是includes。这些算法返回递增后的dest迭代器,表示写入dest的最后一个元素之后的位置。
每种算法都有重载版本,第一个使用元素类型的<运算符,第二个使用给定的比较操作。
includes(beg, end, beg2, end2)includes(beg, end, beg2, end2, comp)//如果第二个序列中每个元素都包含在输入序列中,则返回true。否则返回false。set_union(beg, end, beg2, end2, dest)set_union(beg, end, beg2, end2, dest, comp)//对两个序列中的所有元素,创建它们的有序序列。//两个序列都包含的元素在输出序列中只出现一次。输出序列保存在dest中。set_intersection(beg, end, beg2, end2, dest)set_intersection(beg, end, beg2, end2, dest, comp)//对两个序列都包含的元素创建一个有序序列。结果序列保存在dest中。set_difference(beg, end, beg2, end2, dest)set_difference(beg, end, beg2, end2, dest, comp)//对出现在第一个序列中,但不在第二个序列中的元素,创建一个有序序列。set_synanetric_difference(beg, end, beg2, end2, dest)set_synanetric_clifference(beg, end, beg2, end2, dest, comp)//对只出现在一个序列中的元素,创建一个有序序列。
最小值和最大值
这些算法使用元素类型的<运算符或给定的比较操作。第一组算法对值而非序列进行操作。第二组算法接受一个序列,它们要求输入迭代器。
min(val1, val2)min(val1, val2, comp)max(val1, val2)max(vall, val2, comp)//返回vall和val2中的最小值/最大值//两个实参的类型必须完全一致。参数和返回类型都是const的引用,意味着对象不会被拷贝。min(init_list)min(init_list, comp)max(init_list)max(init_list, comp)//返回initializer_list中的最小值/最大值。//两个实参的类型必须完全一致。参数和返回类型都是const的引用,意味着对象不会被拷贝。minmax(val1, val2)minmax(val1, val2, comp)//返回一个pair,first成员为提供的值中的较小者,second成员为较大者。minmax(init_list)minmax(init_list, comp)//返回一个pair, 其first成员为list中的最小值,second为最大值。min_element(beg, end)min_element(beg, end, comp)//返回指向输入序列中最小元素的迭代器max_element(beg, end)max_element(beg, end, comp)//返回指向输入序列中最大元素的迭代器minmax_element(beg, end)minmax_element(beg, end, comp)//返回一个pair,//first成员为最小元素,//second成员为最大元素。
字典序比较
此算法比较两个序列,根据第一对不相等的元素的相对大小来返回结果。算法使用元
素类型的<运算符或给定的比较操作。两个序列都要求用输入迭代器给出。
lexicographical_compare(beg1, end1, beg2, end2)lexicographical_compare(beg1, end1, beg2, end2, comp)//如果第一个序列在字典序中小于第二个序列,则返回true。否则,返回false。//如果一个序列比另一个短,且所有元素都与较长序列的对应元素相等,//则较短序列在字典序中更小。如果序列长度相等,且对应元素都相等,则在字典序中任何一个都不大于另外一个。
数值算法
数值算法定义在头文件numeric中。这些算法要求输入迭代器;如果算法输出数据,则使用输出迭代器表示目的位置。
accumulate(beg, end, init)accumulate(beg, end, init, binaryOp)//返回输入序列中所有值的和。和的初值从init指定的值开始。//返回类型与init的类型相同。//第一个版本使用元素类型的+运算符,//第二个版本使用指定的二元操作。inneryroduct(begl, endl, beg2, init)inneryroduct(begl, endl, beg2, init,binOpl, bin0p2)//返回两个序列的内积,即对应元素的积的和。//两个序列一起处理,来自两个序列的元素相乘,乘积被累加起来。//和的初值由init指定,init的类型确定了返回类型。//第一个版本使用元素类型的乘法(*)和加法(+)运算符。//第二个版本使用给定的二元操作,使用第一个操作代替加法,第二个操作代替乘法。partial_sum(beg, end, dest)partial_sum(beg, end, dest,binaryOp)//将新序列写入dest, 每个新元素的值都等于输入范围中当前位置和之前位置上所有元素之和。//第一个版本使用元素类型的+运算符;//第二个版本使用指定的二元操作。//算法返回递增后的dest迭代器,指向最后一个写入元素之后的位置。adjacent_difference(beg, end, dest)adjacent_difference(beg, end, dest, binaryOp)//将新序列写入dest, 每个新元素(除了首元素之外)的值都等于输入范围中当前位置和前一个位置元素之差。//第一个版本使用元素类型的-运算符,//第二个版本使用指定的二元操作。iota(beg, end, val)//将val赋予首元素并递增val。//将递增后的值赋予下一个元素,//继续递增val,然后将递增后的值赋予序列中的下一个元素。//继续递增val并将其新值赋予输入序列中的后续元素
