美文网首页
博览网:STL与泛型编程第四周笔记

博览网:STL与泛型编程第四周笔记

作者: 博览网小学员 | 来源:发表于2017-09-11 21:45 被阅读0次

    简书地址:

    1、算法

    基本的C++算法分为三类:排序算法、树算法、图算法

    算法思想有三种:递推、分治、动态规划 以及 贪心算法。

    本节课程中总结:Algorithms看不见Containers,对其一无所知;所以它需要的一切信息都必须从Iterators取得,而Iterators(由Containers供应)必须能够回答Algorithm的所有提问,才能搭配该Algorithm的所有操作。

    一般STL中的算法都是以下两种形式(其中的Algorithm是一种泛指,可以替代其他的函数名称)

    template

    Algorithm (Iterator itr1, Iterator itr2)

    {

    ..........

    }

    template

    Algorithm (Iterator itr1, Iterator itr2, Cmp comp)

    {

    ..........

    }

    因为算法对容器的操作必须通过迭代器来进行,在进行算法的讨论之前有必要对迭代器进行分类。

    1.1迭代器的分类

    Iterator(迭代器)模式又称Cursor(游标)模式,用于提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。或者这样说可能更容易理解:Iterator模式是运用于聚合对象的一种模式,通过运用该模式,使得我们可以在不知道对象内部表示的情况下,按照一定顺序(由iterator提供的方法)访问聚合对象中的各个元素。

    由于Iterator模式的以上特性:与聚合对象耦合,在一定程度上限制了它的广泛运用,一般仅用于底层聚合支持类,如STL的list、vector、stack等容器类及ostream_iterator等扩展iterator。

    迭代器由容器来提供,各种容器的Iterators的5种iterator_category如下:

    (2)通过使用typeid函数来实现迭代器类型的打印:

    1.3iterator_category对算法的影响

    前面说过算法需要迭代器的信息;而不同的算法对于不同的对象进行操作的时候,往往需要根据具体的情况处理。因此,在标准库中,我们表面上看到的算法都是接收迭代器就可以了,实际上算法在与操作对象的交流中早就知道了迭代器的类型,并且根据这个类型做出了不同的判断。这个判断的过程,一般是通过traits来实现的。

    为了实现上述的思想,算法的结构可以大致表现为两个部分:

    主函数部分,作为对外接口

    次函数部分,作为对各种不同迭代器的分情况处理

    下面以具体的例子进行说明。

    (1)distance函数

    distance函数用于计算两个迭代器之间的距离,具体的源代码如下:

    [cpp] view plain copy print?

    template

    inline iterator_traits::difference_type

    _distance(InputIterator first, InputIterator last, input_iterator_tag) {

    iterator_traits::difference_type = 0;

    while (first != last) {

    ++ first;

    ++ n;

    }

    return n;

    }

    template

    inline iterator_traits::difference_type

    _distance(RandomAccessIterator first, RandomAccessIterator last,

    random_access_iterator_tag) {

    return last - first;

    }

    //--------------------------------------

    template

    inline iterator_traits::difference_type

    distance(InputIterator first, InputIterator last) {

    typedef typename

    iterator_traits::iterator_category category;

    return _distance(first, last, category());

    (3)copy函数

    copy函数针对不同类型的Iterator进行了详细的区分和判断,选择最高效的方法来完成复制。

    (4)destroy函数

    destroy函数和copy函数类似,也对不同类型的Iterator进行了详细的区分和判断,选择最高效的方法来完成操作。

    具体源代码及示意图如下所示:

    (5)unique_copy函数

    unique_copy()与之前的实现方法类似,但是要注意的一个地方是这个函数可以接受一个OutputIterator类型的迭代器作为其参数,OutputIterator类型迭代器的一个重要特点是:只写(write only)。具体如下图所示:

    1.4算法对iterator_category的暗示

    算法源代码对迭代器的类型并没有语法上的规定,但是会有暗示,具体如下图所示:

    (4)算法count, count_if

    (4)算法find、find_if

    (5)算法sort

    2.仿函数Functors

    按照功能的不同,仿函数可分为算术类、逻辑类和关系类三种,具体如下图所示:

    标准库提供的functors都继承了binary_function

    template

    struct binary_function {

    typedef Arg1 first_argument_type;

    typedef Arg2 second_argument_type;

    typedef Result result_type;

    }

    继承binary_function的意义在于,告诉算法传进来的是二元运算。仿函数在传递进算法的时候,需要告诉算法两个参与运算的类型,以及一个用于接受结果的类型。

    如果没有继承,在某些场合也可以使用,但是当我们需要修改或者适配它本身的时候很可能就会出问题。

    3.适配器Adapter

    适配器按照类型的不同,可分为容器适配器、迭代器适配器和仿函数适配器三种,具体如下图所示:

    3.1容器适配器

    容器适配器:stack、queue

    template >

    class stack{

    //.......

    public:

    typedef typename Squence::value_type value_type;

    typedef typename Squence::size_type size_type;

    typedef typename Squence::reference reference;

    typedef typename Squence::const_reference const_reference;

    protected:

    Sequence c;  //底层容器

    public:

    bool empty() const {return c.empty();}

    size_type size() const {return c.size();}

    reference top() {return c.back();}

    const_reference top() const {return c.back();}

    void push (const value_type& x) { c.push_back(x);}

    void pop() {c.pop_back();}

    }

    template  >

    class queue{

    //.............

    public:

    typedef typename Squence::value_type value_type;

    typedef typename Squence::size_type size_type;

    typedef typename Squence::reference reference;

    typedef typename Squence::const_reference const_reference;

    protected:

    Sequence c;  //底层容器

    public:

    bool empty() const {return c.empty();}

    size_type size() const {return c.size();}

    reference front() {return c.front();}

    const_reference front() const {return c.front();}

    reference back() {return c.back();}

    const_reference back() const {return c.back();}

    void push (const value_type& x) { c.push_back(x);}

    void pop() {c.pop_front();}

    }

    3.2函数适配器

    函数适配器:binder2nd

    函数适配器:not1

    相关文章

      网友评论

          本文标题:博览网:STL与泛型编程第四周笔记

          本文链接:https://www.haomeiwen.com/subject/dcqqsxtx.html