常用演算法使用样例
演算法包含的头文件 <algorithm> <numeric>
可能用到仿函数和函数配接器 <functional>
几条规则:
1. 演算法都是操作序列内一段区间
- 一般前2个参数是源数据区间iter1、iter2,这两个迭代器指向同一个容器,且保证iter1++能到达iter2;
- 如果有第3个参数那一般是目的区间的首iter,目的区间要保证足够空间,演算法都是覆盖操作,要保证iter不会超出容器。也可以使用inserter迭代器,它的operator=(演算法参数的目的区间迭代器肯定会用到operator=)调用相应容器的push\insert操作;
- 其它的参数可能是op操作,op可以是函数地址或仿函数对象。不同的演算法对op的参数类型和返回值类型有要求。
2. 对此有一些尾词_if和_copy,if要求判断op,copy在原演算法基础上增加iter拷贝目标区间。
3. 容器提供的成员函数一般效率要高于演算法,可以用成员函数的一般不用演算法,除非为了方便地改换容器。(设计时确定使用的容器)
流迭代器 std::ostream_iterator<int> pOut(std::cout, "\n"); 输出,重载了=(const T&){参数1<<T; pOut=参数2;} pOut=*iter;
演算法实例:
for_each(iter1, iter2, op);//对区间里每一个元素执行op操作 void op(T item);
op(T& ); //for_each可以改变源区间的值,只要传引用参数
op不限制返回值类型,因为用不到。可以是int op(),参数可以是T,const T,T2……,但只能是1个参数,因为这个用到了
transform(iter1, iter2, iter, op);//对区间里每一个元素执行op操作赋给目的区间
T op(T item); 返回类型T 不一定要和iter指向类型一样,只要它们能传值。内部操作是*iter=op(*iter1);所以可以iter==iter1,相当于用for_each操作自身
(iter1, iter2, iter3, iter, op);//两个区间元素op
T op(T item, T item);
copy
replace_if
关联式容器不能作为目标容器,比较查找一般也不用演算法
计数、比较、查找
difference_type count(iter1, iter2, const T&); //统计区间中==T的数量 //T不能像上面的赋值操作自动转换类型了
_if( op); //符合op的数量 bool op(T item){比较op内部的条件} //返回bool值,只传1个item
复杂度:线性,顺次比较每一个元素。关联式容器基于二分查找当然提供了效率更高的成员函数count
std::size_t:unsigned类型,指明数组长度或下标 ptrdiff_t:signed类型,同一数组中两个指针之差距
size_type :unsigned,容器元素长度或者下标 difference_type:signed,表示迭代器差距for_each操作自身
iter = min_element(iter1, iter2); //op(*iter1, ()=*iter1++); iter1!=iter2
( ,op); bool op(T item, T item);
复杂度:线性,关联式容器有效率更高的成员函数。
iter = find(iter1, iter2, const T&); // 比较*iter1与T,返回第1个符合条件的iter
_if( , op); // op(*iter1) {比较op内部的条件} bool op(T item){比较op内部的条件} //只传1个item
复杂度:线性,关联式容器有效率更高的成员函数。非关联容器顺序查找如果是已序区间,应该用lower_bound,upper_bound,binary_search等
多次搜索:有时可能在第1次搜索的基础上,在子区间再查找多次,注意判断是否越界
pos1 = find(begin(), end(), T);
if(pos1 != end())
{ find(++pos1, end(), T); } //此时pos+1,==end()会判断
bool = equal(iter1, iter2, iter); //将 [iter1, iter2)与iter打头的区间比较,判断区间是否相等
( , op); //加上op bool op(T item, T item);
pair<> = mismatch(iter1, iter2, iter, op); //区间第1对不相等的元素
find() //搜索元素// find(逆向迭代器);
iter = search(iter,iter,iter,iter); //搜索子区间// find_end(iter,iter,iter,iter);
iter = search_n(iter1, iter2, n, T); //查找连续n个元素