首页 > 代码库 > [GeekBand] STL与泛型编程(3)
[GeekBand] STL与泛型编程(3)
本篇文章主要介绍泛型算法中的变易、排序、数值算法。
一、 变易算法
所谓变易算法是指那些改变容器中的对象的操作。
1.1 copy组
template <class InputIterator, class OutputIterator> OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result); |
Copy操作是将两个输入迭代器之间的元素拷贝到输出迭代器处。注意拷贝时采用的是左对齐,会发生覆盖,使用时应该确保容器具有足够的大小,或者使用inserter迭代器。注意,由于采用的是左对齐的方式,可以实现向量元素的左移。
template <class BidirectionalIterator1, class BidirectionalIterator2> BidirectionalIterator2 copy_backward (BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result); |
与普通的copy对应的,有一种右对齐的拷贝方式copy_backward,指定的输出迭代器为拷贝的末地址。
template <class InputIterator, class OutputIterator> OutputIterator copy_n (InputIterator first, int num, OutputIterator result); |
也可以采用起始迭代器和个数进行拷贝。
template <class InputIterator, class OutputIterator, class UnaryPredicate> OutputIterator copy_if (InputIterator first, InputIterator last, OutputIterator result, UnaryPredicate pred); |
也可以进行if条件的筛选,pred参数可以是函数指针,函数对象,也可以采用匿名函数。
?
1.2 swap组
template <class T> void swap (T& a, T& b); |
Swap操作将a,b两个容器(不是迭代器)中的元素交换。
template <class ForwardIterator1, class ForwardIterator2> ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); |
也可以采用元素区间的方式进行交换。注意这里要求,第一个区间要小于第二个区间。函数的操作是将第一个区间的全部n个元素和第二个区间的前n个元素交换。也就是说,第二个区间后边的元素不会被改变。
1.3 transform
template <class InputIterator, class OutputIterator, class UnaryOperation> OutputIterator transform (InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperation op); |
Transform会把容器中的元素进行相应的"转换",将每个元素丢给op函数进行操作,返回值存到result开始 位置中。如果result == first1,就是完整的转换操作。
template <class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperation> OutputIterator transform (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op); |
这种重载的特点是,最后的操作不再是一个单参操作,而是双参操作。其第一个参数是first1到last1之间的每一个元素,而第二个参数则从first2开始,一一对应的进行选择。
1.4 replace组
template <class ForwardIterator, class T> void replace (ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); |
普通的replace操作是,对于区间内的操作,如果等于old_value,则将其替换为新的值。
template <class ForwardIterator, class UnaryPredicate, class T> void replace_if (ForwardIterator first, ForwardIterator last, UnaryPredicate pred, const T& new_value ); |
也可以进行需要函数判断替换的replace_if操作,将区间内的每个元素扔给函数对象,如果返回值为真则进行替换。
template <class InputIterator, class OutputIterator, class T> OutputIterator replace_copy (InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value); |
Replace_copy操作是将区间内的元素先复制到目的迭代器指定的位置处,注意目的迭代器的容量问题。随后,并且对目的迭代器中的这些元素进行替换操作。
template <class InputIterator, class OutputIterator, class T> OutputIterator replace_copy_if (InputIterator first, InputIterator last, OutputIterator result, UnaryPredicate pred, const T& new_value); |
Replace_copy_if操作就是replace_if的带复制版本。
1.5 fill
template <class ForwardIterator, class T> void fill (ForwardIterator first, ForwardIterator last, const T& val); |
将区间内的元素直接用这个值进行填充。
1.6 generate
template <class ForwardIterator, class Generator> void generate (ForwardIterator first, ForwardIterator last, Generator gen); |
将无参函数gen的返回值放在区间内。通常用于产生随机数,例如:
Generate(v.begin(),v.end(),rand);
1.7 remove组
template <class ForwardIterator, class T> ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val); |
Remove检查区间内的元素,如果相等,则将这个元素删除,最后返回一个迭代器,指向这个被删除后的区间中最后的元素。也就是说,如果原本最后一个元素没有被删除,则指向原本的最后一个元素;如果原本的最后一个元素也被删除了,则往前移动。
template <class ForwardIterator, class UnaryPredicate> ForwardIterator remove_if (ForwardIterator first, ForwardIterator last, UnaryPredicate pred); |
在普通remove的基础上,通过检验判别函数(单参数 )决定是否remove。
template <class InputIterator, class OutputIterator, class T> OutputIterator remove_copy (InputIterator first, InputIterator last, OutputIterator result, const T& val); |
在普通remove的基础上,改为先将其复制到新的位置,再对新的容器进行remove操作。
1.8 unique
template <class ForwardIterator> ForwardIterator unique (ForwardIterator first, ForwardIterator last); ???? template <class ForwardIterator, class BinaryPredicate> ForwardIterator unique (ForwardIterator first, ForwardIterator last, BinaryPredicate pred); |
Unique操作,第一种形式是将相同的元素删除,只保留一份,返回的迭代器和remove操作一样;第二种是通过一个pred函数的返回值来查看是否是一样的,从中可以建立映射。
1.8 reverse
template <class BidirectionalIterator> void reverse (BidirectionalIterator first, BidirectionalIterator last); |
Reverse函数将容器首位倒置,即"123"->"321";
1.9 rotate
template <class ForwardIterator> void rotate (ForwardIterator first, ForwardIterator middle, ForwardIterator last); |
Rotate即翻转操作,以middle为界,把middle前边的元素都移到最末尾,middle成为新的区间头。
1.9 random_shuffle
generator by default (1)???? template <class RandomAccessIterator> void random_shuffle (RandomAccessIterator first, RandomAccessIterator last); ? specific generator (2)???? template <class RandomAccessIterator, class RandomNumberGenerator> void random_shuffle (RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& gen); |
Shuffle即洗牌操作;将元素进行打乱。当进行自定操作时,则可能是N的阶乘中情况中的任何一种。当自定义操作时候,其行为是依次将第i号元素和第gen(i)号元素进行交换,一直到容器底。
1.10 partition
template <class BidirectionalIterator, class UnaryPredicate> BidirectionalIterator partition (BidirectionalIterator first, BidirectionalIterator last, UnaryPredicate pred); |
Partition的行为是按照pred的返回值的true或false进行划分。划分后返回的迭代器result,使得[r.begin(),result )为true,[result,r.end())为false。
二、????排序算法
2.1????普通排序
2.1.1 sort
default (1)???? template <class RandomAccessIterator> void sort (RandomAccessIterator first, RandomAccessIterator last); custom (2)???? template <class RandomAccessIterator, class Compare> void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp); |
Sort有两种形式,第一重型是默认是调用了operator<函数进行比较,小者在前,也可以自行指定,两两相比返回值为1的元素在前。
2.1.2 partial_sort
default (1)???? template <class RandomAccessIterator> void partial_sort (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last); custom (2)???? template <class RandomAccessIterator, class Compare> void partial_sort (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); |
进行部分排序,使得first到middle的元素是有序的,而middle到end的元素是打乱的(具体顺序不定)。这个排序可以用来找到前n大或者前n小的元素。例如,原来v中的元素为3,2,1,4,5,1,0;调用partial_sort(v.begin(),v.begin+4,v.end())后,结果是[0,1,1,2,…..(顺序不定)]
2.1.3 binary_search
default (1)???? template <class ForwardIterator, class T> bool binary_search (ForwardIterator first, ForwardIterator last, const T& val); custom (2)???? template <class ForwardIterator, class T, class Compare> bool binary_search (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); |
在排好序的情况下,进行二分搜索,查找值为val的元素。元素必须先手动排序。
2.1.4 merge
default (1)???? template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); custom (2)???? template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); |
将两个已经排好的序列进行快速有序合并。
2.2 集合排序算法
2.2.1 includes
default (1)???? template <class InputIterator1, class InputIterator2, class OutputIterator> OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result); custom (2)???? template <class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp); |
将两个已经排好的序列进行快速有序合并。
[GeekBand] STL与泛型编程(3)