● 只读算法
int sum = accumulate(vec.begin(), vec.end(), 42);
将sum的值设置为vec的元素之和再加上42.容器内的元素类型必须与第三个实参的类型匹配,或者可转换为第三个实参的类型。
find_first_of
这个算法带有两对迭代器参数来标记两段元素范围,在第一段范围内查找与第二段范围中任意元素匹配的元素,然后返回一个迭代器,指向第一个匹配的元素,如果找不到匹配的元素,则返回第一个范围的end迭代器。这两个迭代器的类型必须精确匹配,只要这两个序列的元素可使用相等(==)操作符进行比较即可。
● 写容器元素的算法
fill(vec.begin(), vec.end(), 0); //reset each element to 0
这个算法只会对输入范围内已存在的元素进行写入操作。
不检查写入操作的算法:
vector<int> vec; //empty vector
fill_n(vec.begin(), 10, 0); //attempts to write to 10(nonexistent) elements in vec
这个fill_n函数的调用将带来灾难性的后果。我们执行要写入10个元素,但这些元素却不存在-vec是空的。
在没有元素的空容器上调用fill_n函数,将会出现严重的运行时错误!
引入back_inserter:
vector<int> vec; //empty vector
fill_n(back_inserter(vec), 10, 0); //appends 10 elements to vec
back_inserter creates an insert iterator that adds elements to vec
fill_n函数每写入一个值,都会通过back_inserter生成的插入迭代器实现。效果相当于在vec上调用push_back,在vec末尾添加10个元素,每个元素的值都是0.
写入到目标迭代器的算法:
vector<int> vec; //empty vector
copy(ilist.begin(), ilist.end(),back_inserter(ivec)); //copy elements from ilist into ivec
copy从输入范围中读取元素,然后将它们赋值给目标ivec。
算法的_copy版本
replace(ilist.begin(), ilist.end(), 0, 42); //replace any element with value of 0 by 42
这个调用将所有值为0的实例替换成42.如果不想改变原来的序列,则调用replace_copy。这个算法将接受第三个参数迭代器实参,指定保存调整后序列的目标位置。
vector<int> vec;
replace_copy(ilist.begin(), ilist.end(), back_inserter(vec),0,42);
调用函数后,ilist没有改变,vec储存ilist的一份副本,而ilist内所有的0在vec中都变成了42.
unique的使用:
该算法删除相邻的重复元素,然后重新排列输入范围内的元素,并且返回一个迭代器,表示无重复的值范围的结束。
注意:原容器的大小并没有改变,只是这些元素的顺序改变了,unique实际上并没有删除任何元素,而是将无重复的元素赋值到序列的前端,从而覆盖相邻的重复元素。unique返回的迭代器指向超出无重复元素范围末端的下一位置。
vector<string>::iterator endUnique = unique(words.begin(), words.end());
words.erase(endUnique, words.end());
● 插入迭代器
C++语言提供了三种插入迭代器,其差别在于插入元素的位置不同。
1.back_inserter,创建使用push_back实现插入的迭代器。
2.front_inserter,创建了使用push_front实现插入。
3.inserter,使用insert实现插入操作。除了所关联的容器外,inserter还带有第二个实参:指向插入起始位置的迭代器。
● iostream迭代器
标准库定义的迭代器有很多种,istream_iterator用于读取输入流, ostream_iterator用于写输出流。这些迭代器将它们所对应的流视为特定类型的元素序列。使用流迭代器时,可以用泛型算法从流对象读取数据(或将数据写到流对象)。
iostream迭代器的构造函数:
1. istream_iterator<T> in(strm);
创建从输入流strm读取T类型对象的istream_iterator对象
2. istream_iterator<T> in;
istream_iterator对象的超出末端迭代器。
3. ostream_iterator<T> out(strm);
创建将T类型的对象写到输出流strm的ostream_iterator对象
4. ostream_iterator<T> out(strm,delim);
创建将T类型的对象写到输出流strm的ostream_iterator对象,在写入过程中使用delim作为元素的分隔符。delim是以空字符结束的字符数组。
istream_iterator<int> cin_it(cin);//read ints from cin
istream_iterator<int> end_of_stream;//end iterator value(eof)
vector<int> vec(cin_it, end_of_stream);
sort(vec.begin(), vec.end());
ostream_iterator<int> output(cout, ” “);
unique_copy(vec.begin(), vec.end(), output);
in: 23 109 45 89 6 34 12 90 34 23 56 23 8 89 23
out:6 8 12 23 34 45 56 89 90 109
● 反向迭代器
反向迭代器是一种反向遍历容器的迭代器。也就是,从最后一个元素到第一个元素遍历容器。反向迭代器将自增(和自减)的含义反过来了:对于反向迭代
器,++ 运算将访问前一个元素,而 — 运算则访问下一个元素。
原vec:0,1,2…9
// 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
1.反向迭代器需要使用自减操作符
从一个既支持 — 也支持 ++ 的迭代器就可以定义反向迭代器,这不用感到吃惊。毕竟,反向迭代器的目的是移动迭代器反向遍历序列。标准容器上的迭代器既支持自增运算,也支持自减运算。但是,流迭代器却不然,由于不能反向遍历流,因此流迭代器不能创建反向迭代器。
2. 如果要输出列表中最后一个单词,可使用反向迭代器:
// find last element in a comma-separated list
string::reverse_iterator rcomma = find(line.rbegin(), line.rend(), ‘,’);
因为此时传递的是 rbegin() 和 rend(),这个函数调用从 line 的最后一个字符开始往回搜索。当 find 完成时,如果列表中有逗号,那么 rcomma 指向其最后一个逗号,即指向反向搜索找到的第一个逗号。如果没有逗号,则 rcomma 的值为 line.rend()。
在尝试输出所找到的单词时,有趣的事情发生了。直接尝试:
// wrong: will generate the word in reverse order
cout << string(line.rbegin(), rcomma) << endl;
会产生假的输出。例如,如果输入是:
FIRST,MIDDLE,LAST
则将输出 TSAL!
使用反向迭代器时,以逆序从后向前处理 string对象。为了得到正确的输出,必须将反向迭代器 line.rbegin() 和 rcomma 转换为从前向后移动的普通迭代器。其实没必要转换 line.rbegin(),因为我们知道转换的结果必定是 line.end()。只需调用所有反向迭代器类型都提供的成员
函数 base 转换 rcomma 即可:
// ok: get a forward iterator and read to end of line
cout << string(rcomma.base(), line.end()) << endl;
● const迭代器和const_iterator 迭代器
const 迭代器呢,你把它理解为 指向对象的 常指针,即指针是常量
const_iterator 迭代器呢,你把它理解为 指向 常对象 的指针,即指针指向的对象是常量
map、set和list类型提供双向迭代器,而string、vector和deque容器上定义的迭代器都是随机访问迭代器,用作访问内置数组元素的指针也是随机访问迭代器。istream_iterator是输入迭代器,而ostream_iterator是输出迭代器。
BY:AloneMonkey