技术开发 频道

泛型算法

  四、泛型算法中使用迭代器

 1、插入迭代器

 1.1 back_inserter,创建使用 push_back 实现插入的迭代器。

 1.2 front_inserter,使用 push_front 实现插入。该函数将创建一个迭代器,调用它所关联的基础容器的 push_front 成员函数代替赋值操作。只有当容器提供 push_front 操作时,才能使用 front_inserter。在 vector 或其他没有 push_front 运算的容器上使用 front_inserter,将产生错误。

 1.3 inserter,使用 insert 实现插入操作。这种适配器带有两个实参:所关联的容器和指示起始插入位置的迭代器。

 // position an iterator into ilst

 list<int>::iterator it =

 find (ilst.begin(), ilst.end(), 42);

 // insert replaced copies of ivec at that point in ilst

 replace_copy (ivec.begin(), ivec.end(),

 inserter (ilst, it), 100, 0);

 1.4 也许我们会认为可使用 inserter 和容器的 begin 迭代器来模拟 front_inserter 的效果。然而,inserter 的行为与 front_inserter 的有很大差别。在使用 front_inserter 时,元素始终在容器的第一个元素前面插入。而使用 inserter 时,元素则在指定位置前面插入。即使此指定位置初始化为容器中的第一个元素,但是,一旦在该位置前插入一个新元素后,插入位置就不再是容器的首元素了:

 list<int> ilst, ilst2, ilst3;

 // after this loop ilst contains: 3 2 1 0

 for (list<int>::size_type i = 0; i != 4; ++i)

 ilst.push_front(i);

 // after copy ilst2 contains: 0 1 2 3

 copy (ilst.begin(), ilst.end(), front_inserter(ilst2));

 // after copy, ilst3 contains: 3 2 1 0

 copy (ilst.begin(), ilst.end(), inserter (ilst3, ilst3.begin()));

 2、iostream 迭代器

 虽然 iostream 类型不是容器,但标准库同样提供了在 iostream 对象上使用的迭代器: istream_iterator用于读取输入流,而ostream_iterator则用于写输出流。这些迭代器将它们所对应的流视为特定类型的元素序列。使用流迭代器时,可以用泛型算法从流对象中读数据(或将数据写到流对象中)。

2.1 可使用 istream_iterator 对象将标准输入读到 vector 对象中。

 istream_iterator<int> in_iter(cin); // read ints from cin

 istream_iterator<int> eof; // istream "end" iterator

 // read until end of file, storing what was read in vec

 while (in_iter != eof)

 // increment advances the stream to the next value

 // dereference reads next value from the istream

 vec.push_back(*in_iter++);

 2.2 可使用 ostream_iterator 对象将一个值序列写入流中,其操作的过程与使用迭代器将一组值逐个赋给容器中的元素相同:

 // write one string per line to the standard output

 ostream_iterator<string> out_iter(cout, "\n");

 // read strings from standard input and the end iterator

 istream_iterator<string> in_iter(cin), eof;

 // read until eof and write what was read to the standard output

 while (in_iter != eof)

 // write value of in_iter to standard output

 // and then increment the iterator to get the next value from cin

 *out_iter++ = *in_iter++;

  2.3 流迭代器d的几个重要限制:

 不可能从 ostream_iterator 对象读入,也不可能写到 istream_iterator 对象中。

 一旦给 ostream_iterator 对象赋了一个值,写入就提交了。赋值后,没有办法再改变这个值。此外,ostream_iterator 对象中每个不同的值都只能正好输出一次。

 ostream_iterator 没有 -> 操作符。

 3、反向迭代器

 反向迭代器是一种反向遍历容器的迭代器。也就是,从最后一个元素到第一个元素遍历容器。反向迭代器将自增(和自减)的含义反过来了:对于反向迭代器,++ 运算将访问前一个元素,而 -- 运算则访问下一个元素。

 // reverse iterator of vector from back to front

 vector<int>::reverse_iterator r_iter;

 for (r_iter = vec.rbegin(); // binds r_iter to last element

 r_iter != vec.rend();  // rend refers 1 before 1st element

 ++r_iter)              // decrements iterator one element

 cout << *r_iter << endl;    // prints 9,8,7,...0

 4、const 迭代器

 在之前使用 find 的程序中,我们将 result 定义为 const_iterator 类型。这样做是因为我们不希望使用这个迭代器来修改容器中的元素。find_first_of程序中也不打算改变容器内的任何元素,但是它却使用了普通的非 const 迭代器来保存 find_first_of 的返回值。

 原因是,在第二个例子中,程序将迭代器用作 find_first_of 的实参:

 find_first_of(it, roster1.end(), roster2.begin(), roster2.end())

 该函数调用的输入范围由 it 和调用 roster1.end() 返回的迭代器指定。算法要求用于指定范围的两个迭代器必须具有完全一样的类型。roster1.end() 返回的迭代器依赖于 roster1 的类型。如果该容器是 const 对象,则返回的迭代器是 const_iterator 类型;否则,就是普通的 iterator 类型。在这个程序中,roster1 不是 const 对象,因而 end 返回的只是一个普通的迭代器。

 5、迭代器分类

 Input iterator(输入迭代器)              读,不能写;只支持自增运算

 Output iterator(输出迭代器)             写,不能读;只支持自增运算

 Forward iterator(前向迭代器)            读和写;只支持自增运算

 Bidirectional iterator(双向迭代器)      读和写;支持自增和自减运算

 Random access iterator(随机访问迭代器)  读和写;支持完整的迭代器算术运算

查看原文地址

0
相关文章