泛型算法与容器一样,具有统一的设计基础。理解泛型算法的结构有利于学习和使用算法。c++提供了超过一百个算法,了解他们的结构,显然比死记硬背要更好。
算法的形参模式
一般来说,有四种形式
1、alg(beg,end,other parms)
2、alg(beg,end,dest,other parms)
3、alg(beg,end,beg2,other parms)
4、alg(beg,end,beg2,end2,other parms)
其中,alg是算法名称。
beg和end是制定算法操作的元素范围,通常将这个范围称为输入范围,采用左闭合区间机制。
dest,beg2,end2它们都是迭代器。
1、带有单个目标迭代器的算法
dest形参是一个迭代器,用于指定存储输出数据的目标对象。算法假定无论需要写入多少个元素都是安全的。
例如:copy(begin,end,dest)用于将输入范围的元素复制到从dest指向的元素开始的序列。
注意:调用这些算法时,一定要保证目标容器有足够大的容量来容纳输出数据,通常来说要使用插入迭代器或者ostream_iterator来调用这些算法。
2、带第二个输入序列的算法
有一些算法带有beg2迭代器形参,或带有beg2和end2迭代器形参,用来指定第二个输入范围。这类算法通常联合两个输入范围的元素来完成计算。
例如:find_first_of(beg1,end1,beg2,end2);这个算法返回第一个输入范围的迭代器,此迭代器指向第二个范围的任意元素在第一个范围的首次出现的迭代器。
带有beg2而不带有end2的算法,beg2视为第二个输入范围的首元素,但没有指定该范围的最后一个元素。这些算法假定以beg2为起始的范围至少与beg和end的范围一样大。
算法的命名规则
1、带有一个值或一个谓词函数参数的算法版本
很多算法通过检查其输入范围的内的元素实现其功能。这些算法通常要用到标准关系操作符==或<。其中大部分的算法都提供第二个带有谓词函数的版本,允许用户通过自定义比较函数来取代操作符。
例如:
sort(beg,end);
sort(beg,end,comp);
sort是重载的,第一个版本使用默认的<操作符进行排序,结果当然是从小到大排列。而第二个版本则是允许用户重写比较函数,以实现不同规则的排序。
又例如:
find(beg,end,val);
find_if(beg,end,pred);
这与sort不同,find并没有设计为重载,而是设计了另外一个版本,后缀_if。第一个版本默认使用==操作符,而第二个版本则允许用户自定义比较操作,以实现不同规则的查找。
2、实现复制的算法版本
算法有可能改变元素范围内的元素顺序。在默认情况下,原有序列会被改变。stl提供了另外命名的版本,将元素写到指定的输出目标,原有序列不变,这就是_copy版本。
例如:
reverse(beg,end);
reverse_copy(beg,end,dest);
第一个算法将输入范围内的元素逆向排列。
第二个算法则是将输入范围内的元素复制到以dest开始的序列,然后进行逆向排序,而原输入范围内的元素不变。