find 运算: 形参:两个迭代器,检查两个迭代器实参标记范围内的每一个元素。找到与给定值的元素,返回指向该元素的迭代器;如果没匹配元素,这返回第二个形参。
注意: 泛型算法从不执行容器操作,单独依赖迭代器和迭代器操作实现,算法基于迭代器及其操作实现,而并非基于容器操作。
泛型算法 头文件 <algorithm>
泛化的算术算法 头文件 <numeric>
只读算法:
accumulate(begin,end, 初值); 在初值的基础上累加迭代器范围内的元素和。返回结果的类型是初值的类型
注意:初值是必须的,算法通过初值确定迭代器累加元素的类型。
find_first_of( 查找的地方一对迭代器, 目标值的一对迭代器);两对迭代器之间元素只要可以使用== 操作符比较即可。
写容器元素的算法:
1、写入输入序列的元素: 传入的实参是 一对迭代器( bed,end ) ,只在指定范围内写入
EX: fill( vec.begin(), vec.end(),0);
2、不检查写入操作的算法: 参数: 一个迭代器、 一个计数器 以及一个值。
EX: fill( vec.begin(), 10, 0) ; // 从vec 的begin开始,写入10个元素。
注意:这种操作是假设对指定的元素写操作是安全的,所以不检查目标的大小是否足以存储要写入的元素, 如果目标大小< 要写入的元素, 会导致严重的运行时错误。
3、back_inserter 头文件<iterator>
back_inserter 是迭代器适配器. 传递给back_inserter 的实参是一个容器的引用, back_inserter 生成一个绑定在该容器上的插入迭代器。试图通过这个迭代器给元素赋值时,赋值运算将调用push_back 在容器添加一个指定值的元素。
EX: vector<int> vec;
fill_n( back_inserter(vec), 10, 0);
4、写入目标迭代器的算法:向迭代器写入未知个数的元素。
EX copy ( list.begin(), list.end(), back_inserter(vec)) ;
头两个指定输入范围, 第三个指定目标序列的一个元素。
算法的 _copy 版本:
对输入序列的元素做出处理,但不修改原来的元素,而是创建一个新序列存储元素的处理结果
EX:
replace( list.begin(), list.end(), 0, 42) ; // 把 begin 和 end 之间值为0 的元素 替换为42.
replace_copy( list.begin(), list.end(), back_inserter(ivec), 0, 42) ; // 调用函数后,list 没有改变,而是把改变了的list复制给了ivec。
unique 使用:
带有两个指定元素范围的迭代器参数。该算法“删除”相邻的重复元素。 其实就是重新排列了元素,把重复的元素排到序列的后面,所以序列的前半部分就是不重复的序列。 函数的返回 一个迭代器,指向无重复元素的下一个位置。
排序算法:
sort 和 stable_sort : 后者保留了相等元素的原始相对位置。
迭代器: 头文件 <iterator>
1) 插入迭代器
插入器: 迭代器适配器,带有容器函数,生成一个迭代器。用于在指定容器中插入元素。
三种插入器: back_inserter : 创建使用 push_back 的迭代器
front_inserter : push_front
insert: insert ,带有两个参数:容器; 插入起始位置的迭代器
2) iostream 迭代器
istream_iterator 用于读取输入流
ostream_iterator 用于写输出流
iostream 迭代器构造函数:
istream_iterator<T> in (strm) ; 创建从输入流strm 中读取 T 类型对象 的istream_iterator对象
istream_iterator<T> in; istream_iterator 对象的超出末端迭代器
ostream_iterator <T> in(strm); 创建将T类型的对象写到输出流strm 的ostream_iterator 对象。
ostream_iterator <T> in(strm, delim); 同上,在写入过程中使用delim作为元素的分隔符。 delim 是以空字符结束的字符串(c风格字符串)
注意: ostream_iterator对象必须与特定的流绑定在一起。
istream_iterator 如果不提供实参,则该迭代器指向超出末端位置。
ostream_iterator 分隔符必须是c 风格字符串。
EX:
istream_iterator<int> in_iter(cin);
istream_iterator<int> eof;
vector<int> vec (in_iter,eof);
流迭代器的限制:
不能从 ostream_iterator 对象读入,不能写入 istream_iterator
ostream_iterator 赋值后就不能修改了
ostream_iterator 没有 ->操作符
习题 11.18
int main(int argc, char** argv)
{
if(argc < 3)
throw runtime_error(" no enough input file ");
ofstream even_file, odd_file;
if(!open_file(even_file,argv[1]) || !open_file(odd_file,argv[2]))
throw runtime_error( " open file fail " );
ostream_iterator <int>even_ost(even_file," "), odd_ost(odd_file," ");
istream_iterator <int>ist(cin),eof;
while(ist!=eof)
{
if(*ist&1)
*odd_ost++ = *ist;
else
*even_ost++ = *ist;
ist++;
}
}
3)反向迭代器
反向迭代器需要使用自减操作符。 流迭代器不能创建反向迭代器反向迭代器与其他迭代器的关系 . base();
迭代器种类:
1) 输入迭代器: 读,不能写,只支持自增运算。
2) 输出迭代器: 写,不能读,只支持自增运算。
3) 前向迭代器: 读写, 只支持自增运算。
4) 双向迭代器: 读写: 自增,自减
5) 随机访问迭代器:读写 完整的迭代器运算。
重新对容器元素排序的算法要使用< 操作符,重载版本带有一个额外的形参,表示对于元素排序的不同运算
sort( beg, end);
sort( beg, end, comp);
检查指定值的算法默认使用== 操作符。 这类算法的另外命名的版本,带有谓词函数形参,名字带有后缀_if
find (beg ,end ,val); // 找到第一个值为 val 的
find_if (beg ,end , pred); // 找到第一个使pred 为 true 的元素
实现复制的算法版本:
默认情况下,这些算法将重新排列的元素写回其输入范围, 可以使用_copy 版本 将元素写入指定的输出目标。
EX: reverse( beg, end);
reverse_copy( beg, end, dest);