【STL】《STL源码剖析》读书笔记
算法
算法可分为质变算法和非质变算法,质变算法改变操作对象的值,通常提供两个版本,一个直接改变操作对象值,另一种是拷贝一份操作对象并改变,最后返回改变后的副本;非质变算法不会改变操作对象的值。使用算法必须包含头文件<algorithm>。
1.数值算法
使用SGI版STL数值算法需要包含头文件<stl_numeric.h>
1.1 accumulate
template<class InputIterator, calss T>
T accumulate (InputIterator first, InputIterator last, T init)
算法将[first,last)迭代器区间内的值累加到init上,使用时需要初始化init参数,防止迭代器区间失效导致返回一个不可预知的值。
1.2 adjacent_difference
template<class InputIterator, class OutputIterator>
OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result)
算法计算[fist,last)区间内相邻元素的差值。
1.3 inner_product
template<class InputIterator, calss T>
T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 ,T init)
算法计算两个区间的内积,第二个区间长度和第一个区间一样,结果存储在init内返回,init同上需要初始化。如[1,2,3],[4,5,6,7]返回[1*4+2*5+3*6]。
1.4 partial_sum
template<class InputIterator, class OutputIterator>
OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result)
算法计算局部总和,例如:*result的值为*first,*(result+1)的值为*first+*(first+1),以此类推。传入区间[1,2,3,4],返回[1,3,6,10]。
1.5 power
template<class T, class Integer>
inline T power(T x, Integer n) //版本1
template<class T, class Integer, class MonoidOperation>
T power(T x, Integer n, MonoidOperation op) //版本2
算法是SGI专属,计算X的N次方。版本2可以指定操作符,如果指定乘法,依然是X的N次方。
1.6 iota
template <class ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T value)
它不是itoa,看起来很像,但是该算法是指定[first,last)区间的内容为value,value+1,value+2…并不是int转字符串的itoa。
2.基本算法
SGI版STL把常用的一些算法定义在<stl_algobase.h>中,也就是这里说的基本算法。
2.1 equal
template<class InputIterator1 , class InputIterator2>
inline bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) //版本1
template<class InputIterator1 , class InputIterator2,class BinaryPredicate>
inline bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate) //版本2
版本1使用元素类型默认的相等操作符比较两个序列在[first,last)区间内是否相等,版本2可提供自定义仿函数作为比较依据。序列2若比序列1长,多出的元素不在比较范围内,所以使用之前可以自己判断两个区间元素个数是否相同。
2.2 fill
template <class ForwardIterator, class T>
void fill(ForwardIterator first, ForwardIterator last, const T& value)
填充区间[first,last)的值为value。
2.3 fill_n
tempalte<class OutputIterator, class Size, class T>
OutputIterator fill_n(OutputIterator first , Size n, const T& value)
填充[first,last)的前n个元素的值为value。注意,n不能超过区间的size。
2.4 iter_swap
template<class ForwardIterator1, class ForwardIterator2>
inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b)
算法将两个迭代器所指向的对象对调。[1,2,3][4,5,6],若a指向第一个区间的1,b指向第二个区间的5,调用后结果[5,2,3],[4,1,6],将1和5位置对调。
2.5 lexicographical_compare
template<class InputIterator1, class InputIterator2 >
bool lexicographical_compare(InputIterator1 first, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2)
//SGI特化版本,增进了效率,内部比较长度相同的一段使用的是C语言的memcmp
inline bool lexcicographical_compare(const unsigned char* first1, const unsigned char* last1, const unsigned char* first2,const unsigned char* last2)
以字典排列方式对[first1,last1),[first2,last2)两个序列进行比较,序列1小于序列2返回true,否则返回false。比较的是ASCII码值。
2.6 max
tempalte<class T>
inline const T& max(const T& a, const T& b) //版本1
tempalte<class T, class Compare>
inline const T& max(const T& a, const T& b, compare comp) //版本2
取连个参数的最大值,版本2可传入自定义仿函数,使用仿函数判断大小。
2.7 min
tempalte<class T>
inline const T& min(const T& a, const T& b) //版本1
template<class T, class Compare>
inline const T& min(const T& a, const T& b, Compare comp) //版本2
去两个数中最小值。
2.8 mismatch
template <calss InputIterator1, class InputIterator2 >
pari<InputIterator1,InputIterator2> mismatch(InputIterator1 first1, InputIterator last1, InputIterator2 first2)
算法返回两个序列第一个不相等的位置,也有两个版本,第一个版本使用默认比较运算符,第二个版本可以使用自定义的仿函数比较,若第二个序列比第一个长,忽略多出来的元素,若第二个序列比第一个短,会发生未可预期的行为。
2.9 swap
tempalte <class T>
inline void swap(T& a, T& b)
交换a,b两个对象的内容。
2.10 copy
template<class InputIterator, class OutputIterator>
inline OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result)
将[first,last)区间内的元素复制到[result,result+(last-first)]区间内。SGI版copy使用了函数重载,类型萃取,偏特化等技巧加强该算法效率。类型萃取得到操作对象的类型,由类型是否可以直接赋值区分接下来需要调用的函数,平凡类型(如int,bool,char等等)直接赋值效率最高,string等其他非平凡类型调用memmove。
2.11 copy_backward
tempalte<class BidirectionalIterator1, class BidirectionalIterator2>
inline BidiectionalIterator2 copy_backward(BidiectionalIterator1 first,BidiectionalIterator1 last, BidiectionalIterator2 result)
逆向复制的方式复制到逆行区间上,实现与copy相似,具体来说就是*(result-1) =*(last-1),*(result-2) = *(last-2),…以此类推。
3.set相关的算法
与set相关的算法有:两个set的并集,交集,差集,对称差集,四种,适用于STL的set/multiset,也就是元素必须有序,可以重复也可以不重复的区间,hash_set/hash_multiset因为元素无序,故不适用这四种算法。
3.1 set_union
template<class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_union(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
算法构造出两个set区间的有序并集,返回的迭代器指向输出区间的尾端,属于稳定的算法,两个区间元素相对位置不会发生变化,重复的元素会全部出现在结果区间内。
3.2 set_intersection
template<class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
算法构造两个set区间的交集,返回的迭代器依然指向结果尾端,若一个元素重复在两个区间出现,如在set1中出现2次,set2中出现3次,结果集中会出现2次,既min(2,3)。该算法也是稳定的算法。
3.3 set_difference
template<class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
算法构造两个set区间的差集,结果为出现在第一个区间内,但是没有出现在第二个区间内的元素,返回的迭代器指向结果区间尾端。
3.4 set_symmetric_difference
template<class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_symmetric_difference(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
算法构造两个set区间的对称差集,结果是出现在第一个区间但是没有出现在第二个区间和出现的第二个区间但是没有出现在第一个区间的并集。既(S1-S2)U(S2-S1)。返回值依然是指向结果尾端的迭代器。
4.其他算法
4.1 count
template<class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type count(InputIterator first, InputIterator last, const T& value)
统计[first,last)区间内有多少和value相等的元素,返回计数器。
4.2 find
template<class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T& value)
查找[first,last)区间内第一个value出现的位置,返回指向这个位置的迭代器。
4.3 for_each
template<class InputIterator, class Function>
Function for_ecah(InputIterator first, InputIterator last, Function f)
将仿函数f施行与[first,last)的每一个元素身上。由于first和last都是InputIterator类型,所以仿函数不能改变元素内容。
4.4 merge
template<class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator merge(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result)
合并两个有序区间,返回结果序列的尾端迭代器。
4.5 remove
template<class ForwardIterator ,class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last, const T& value)
移除[first,last)区间内等于value的元素,但是并没有真正删除,算法会把不等于value的元素分别拷贝到前面,返回的迭代器指向整理后的最后元素的下一个位置。
4.6 transform
template<class InputIterator, class OutputIterator, class UnaryOperation>
OutputIterator transform(InputIterator first, InputIterator last, OutIterator result, UnaryOperation op)
以仿函数op作用于[first,last)区间的每一个元素,产生一个新序列result,返回值指向结果序列的最后一个元素的下一位置。