算法的选择
泛型算法为这些容器类型和两个内置数组类型的元素提供了操作。这些操作包括Search (find, count), Sort (merge, partition, permutate, reverse, rotate, shuffle, sort), Deletion/Subtitution (remove, replace, swap, unique), Copy, Relational (equal, min, max, includes), Generate (fill, for-each, generate, transform), Set (union, intersection, difference), Heap (make, sort, pop, push), 以及很多深奥的数字操作,例如积分,部分求和,内积(inner product),和临差(adjacent difference)。
在我们使用泛型算法前,当然,我们必须包含进相应的头文件。除了数字算法之外的其它所有算法,我们都这样写:
四个数字算法,积分,部分求和,内积,和临差被分出一个单独的头文件。在使用这些算法的时候我们这样写头文件:
(我一直在寻求为什么这四个操作的头文件被单独的提出来的原因—这显然将算法的使用的讨论复杂化—但是无论是在文档中还是经过深入的研究,我仍然找不到答案。在原先Stepanov的实现中,这四个操作与其它的算法使用的是同一个头文件。在标准化过程中, numeric头文件被引入了并且在数字库标准选举部分确实做了一个讨论。)
你可能会想,天哪,Stan,这些不应当写作吗?毕竟,这是容器头文件的验证方法。如果那样写的话不是有点弄巧成拙么?令人吃惊的是,答案是“不”。我说令人吃惊的是因为STL和STL.NET中采用了相同的实现方法。天哪,我们讨论到了代码重用去了!
好的。让我们看看如何使用这些算法。举例来说,让我们在将字符串元素数组插入map之前对它们进行排序。我们将使用sort()泛型算法来实现它。对于所有的泛型算法,参数几乎都是迭代器对构成的范围:
sort( &as[0], &as[ as->Length ] ); |
在开始的代码中还要使用到另外两个泛型算法—find()和remove():
//泛型算法:find
vector::iterator iter = find( svec->begin(), svec->end(), "Pooh" );
if ( iter != svec->end() ){ ... }
//泛型算法:remove……
remove( svec->begin(), svec->end(), "Rabbit" ); |
到现在为止我们应当对这里的用法模式非常敏感了:由迭代器对划分出的范围与容器的算法密不可分。搜索算法返回一个迭代器,或者用于发现容器中的项,抑或是找不到,迭代器用于标识范围内的最后一个项。
我们将用泛型算法做一些有趣的事情—但这必须在后续的文章中完成。我希望这些内容给我们了一个我们将要讨论什么的不错的概览,并且为我们能够作为一个学习小组向前走提供了一个公共的词汇表和背景知识。
查看本文来源