1 、算法的泛化过程
泛化过程:把操作对象的型别加以抽象化,把操作对象的标示法和区间目标的移动行为抽象化,整个算法也就在一个抽象层面上工作了。
int *find(int * arrayHead,int arraySize,int value)
{
for(int i=0;i<arraySize;++i)
if(arrayHead[i]==value)
break;
return &(arrayHead[i]);
}
为适合更多不同类型的容器,改用指针:
int *find(int *begin,int*end,int value)
{
while(begin!=end && *begin !=value)
++begin;
return begin;
}
为适应更多不同类型的数据,采用模板:
template<typename T>
T* find(T* bgin,T* end,constT& value)
{
while(begin !=end && *begin !=value)
++begin;
return begin;
}
进一步使函数能适应更多的类似指针的对象:
template<classIterator,class T>
Iteratorfind(Iterator begin,Iterator end,const T& value)
{
while(begin !=end && *begin !=value)
++begin;
return begin;
}
由上可知,泛化就是一步步使函数的适用范围更广。
2、 主要算法介绍
在《STL源码剖析》一书中,将算法分为以下几类分别进行讲解:数值算法、基本算法、set相关算法、heap算法、其他算法。其中最重要的当属基本算法,另外其他算法中存在较复杂的算法。
2.1、 数值算法中的power
该函数主要用来计算某数的n幂次方,默认为乘幂。主要代码如下:
template<classT,class Integer,class MonoidOperation>
Tpower(T x,Integer n,MonoidOperation op)
{
if(n==0)
return identity_element(op);
else
{
while((n&1)==0)
{
n >>=1;
x=op(x,x);
}
T result=x;
n >>=1;
while(n!=0)
{
x=op(x,x);
if((n&1)!=0)
result=op(result,x);
n >>=1;
}
return result;
}
}
该函数设计十分巧妙,充分利用了已经算好的低次幂的结果,减少了计算量,大大提高了算法的效率。具体思想介绍可参考以下链接文章:http://www.cnblogs.com/ziyoudefeng/archive/2012/07/17/2594852.html
2.2、 基本算法之copy
针对不同的参数,调用不同的底层函数,强化效率无所不用其极。
2.3、 其他算法
rotate函数用于将容器内区间元素按照某个中间节点旋转。如[first,middle)内的元素和[middle,last)内的元素互换。书中列出多种实现方法,其中针对随机访问的迭代器的实现方法非常巧妙,高效。具体代码如下:
template<classRandomAccessIterator,class Distance>
void__rotate(RandomAccessIterator first,RandomAccessIteratormiddle,RandomAccessIterator last,Distance*,random_access_iterator_tag)
{
Distance n=__gcd(last-first,middle-first);
while(n--)
__rotate_cycle(first,last,first+n,middle-first,value_type(first));
}
template<classRandomAccessIterator,class Distance,class T>
void__rotate_cycle(RandomAccessIterator first,RandomAccessIterator last,RandomAccessIteratorinitial,Distance shift,T*)
{
T value=*initial;
RandomAccessIterator ptr1=initial;
RandomAccessIterator ptr2=ptr1+shift;
while(ptr2!=initial)
{
*ptr1=*ptr2;
ptr1=ptr2;
if(last-ptr2>shift)
ptr2+=shift;
else
ptr2=first+(shift-(last-ptr2));
}
*ptr1=value;
}
具体思想已经在本博客另一篇文章中有详细说明,详见:
http://blog.csdn.net/zhiren2011/article/details/39718787