《STL源码剖析》学习笔记系列之六——算法(1)


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值