• 迭代器和辅助函数


    

    迭代器(iterator)是连接容器和算法的纽带,为数据提供了抽象,使写算法的人不必关心各种数据结构的细节。迭代器提供了数据访问的标准模型——对象序列,使对容器更广泛的访问操作成为可能。

    根据迭代器所支持的操作不同,在STL中定义了如下5种迭代器:

    迭代器类别 说明
    输入 从容器中读取元素。输入迭代器只能一次读入一个元素向前移动,输入迭代器只支持一遍算法,同一个输入迭代器不能遍历一个序列两遍
    输出 向容器中写入元素。输出迭代器只能一次一个元素向前移动。输出迭代器只支持一遍算法,同一输出迭代器不能两次遍历一个序列
    正向 具有输入迭代器的全部功能和输出迭代器的大部分功能
    双向 具有正向迭代器和逆向迭代器的功能,支持多遍算法
    随机访问

    具有双向迭代器的功能与直接访问容器中任何元素的功能,即可向前向后跳过任意个元素

    迭代器的层次结构:

    上面这图表并不是表明它们之间的继承关系:而只是描述了迭代器的种类和接口。


    迭代器能力:

     

     

    输入

    输出

    前向

    双向

    随机访问

    读取(= *i)

     

    ×

    写入(*i =)

     

    ×

    多通

     

    ×

    ×

    ++ii++

     

    --ii--

     

    ×

    ×

    ×

    i[n]

     

    ×

    ×

    ×

    ×

    i + ni - n

     

    ×

    ×

    ×

    ×

    i += ni -= n

     

    ×

    ×

    ×

    ×

    == !=

     

    ×

    < >

     

    ×

    ×

    ×

    ×

    <= >=

     

    ×

    ×

    ×

    ×


    迭代器多通是指以同样的顺序来遍历容器,而且迭代器递增后,仍然可以通过解除保存的迭代器引用,来获得同样的值。


    为何Forward迭代器不具备Output迭代器的全部功能?

    这是因为有一个约束条件,使得某些对Output Iterator有效的程序对Forward Iterator可能无效。

    1. 面对Output Iterator无须检查其是否抵达序列尾端,便可直接写入数据。事实上由于Output Iterator不提供比较操作,因此无法将Output Iterator与end-of-sequence相比较。以下循环是正确的:
         while(true)
         {
          *pos = foo();
          ++pos;
         }
    2. 对于Forward Iterator,必须在提领数据之前确保其有效,因此上述循环对Forward Iterator是错误的。对于Forward Iterator上述循环应改为:
          while( pos != coll.end() )
         {
          *pos = foo();
          ++pos;
         }
       而同时,该循环不适用于Output Iterator,因为Output Iterator没有operator!=


    *将迭代器移至“起点更前面或end()之后”都会引起未定义行为。


    vecotr迭代器的递增和递减

    迭代器的递增和递减操作有个奇怪的问题。一般而言你可以递增或递增暂时性迭代器,但对于vectors和strings就不行,如下:

            vector<int> coll;
    	coll.push_back(1);
    	coll.push_back(3);
    	coll.push_back(2);
    	coll.push_back(4);
    	if (coll.size() > 1)
    	{
    		sort(++coll.begin(), coll.end()); //vs2013下能运行,因为实现为模板class
    	}
    	copy(coll.begin(), coll.end(), ostream_iterator<int>(cout, " "));

    C++不允许你修改任何基本型别(包括指针)的暂时值,但对于struct和class则允许。因此如果迭代器被实作为一般指针,上面代码编译会失败。如编译不通过可以改为:

            vector<int>::iterator it = coll.begin();
            sort(++it, coll.end());



    迭代器的辅助函数

    #include<iterator>

    void advance(InputIterator pos,int n);   

    不检查迭代器是否超过end(), 无返回值。


    #include<iterator>

    iterator_traits<InputIterator>::difference_type distance(InputIterator pos1,InputIterator pos2);

    两个迭代器都必须指向同一个容器,从pos1必须能到达pos2


    #include<algorithm>

    void iter_swap(ForwardIteraor1 pos1,ForwardIteraor2 pos2);

     迭代器型别不一定相同,但pos1和pos2的内容可相互赋值,交换迭代器pos1和pos2所指的值。



  • 相关阅读:
    Codeforces 220C
    Codeforces 697D
    HDU 4417
    Codeforces 396C
    Codeforces 246C
    HDU 6333
    HDU 3389
    总结:树上启发式合并
    HDU 6319
    Codeforces 1009G
  • 原文地址:https://www.cnblogs.com/ggzone/p/4052433.html
Copyright © 2020-2023  润新知