generic algorithm
2017-09-13 16:54
155 查看
generic algorithm(泛型算法)
可用于不同元素/容器类型
算法运行于迭代器之上,不会执行容器操作。所以算法不会直接添加或者删除元素。
由于算法可以依靠迭代器完成大部分的操作,所以并不需要依靠容器的类型;但是依赖元素类型提供的操作。
大多数标准库算法对2个迭代器(第2个为尾后迭代器)表示的范围进行操作。
插入算法都假定具有足够空间
对于list和forward_list应优先使用成员函数版本CP369
命名规范
一些算法允许通过重载传递谓词
_if代表函数使用谓词来代替元素值
_copy代表将处理结果写入到额外的目的空间(同时写回输入序列)
形参形式
只读算法:
如果算法只访问并不改变元素,建议使用cbegin()和cend()
对于操作2个序列的算法:
序列的容器类型可以不填
用单一迭代器表示第2个序列编译器假定第2个序列和第1个序列一样长。
find
find_if:寻找第一个具有某种特征的值
接收3个参数
第3个参数为谓词
不存在时返回尾后迭代器
accumulate:求和
接收3个参数
第3个参数为和的初值,决定加法运算符的类型和返回类型
序列中的元素类型必须能和第3个参数的类型匹配,并定义了+运算符
equal:比较序列是否相同
接收3个参数
第3个参数为第2个序列的首元素
只写算法:
确保原大小必须等于/大于算法写入的元素数目
编译器假定有足够的空间,不会进行检查
fill:将给定的值赋给序列中的每个元素
接收3个参数
第3个参数被赋值的元素
fill_n
copy
接收3个参数
第3个参数表示目的序列的起始位置
必须确保目的序列的容量
返回目的迭代器之后的值
replace:将序列中指定的值都替换成新值
接收4个参数
第3个参数表示需要替换的值
replace_copy:将改变后的原序列的备份保存到别的地方
相比replace额外接收第3个迭代器参数指出保存位置
排序算法
sort
unique:将重复的元素放在输入序列的最后,返回指向非重复序列之后的迭代器
5标准库允许算法提供自己定义的操作来代替运算符
谓词:
返回值可作为条件的表达式
一元谓词:接收1个参数
二元谓词:接收2个参数
例如
可调用对象:可以使用(args)(调用运算符)
函数:适用于在多个地方重复使用
函数指针
重载调用运算符的类
如果类定义了调用运算符,则该类对象称作函数对象。
例如
标准库的函数对象CP510:可以代替运算符
可用于泛型算法的实参
lambda表达式:适用于只需要在少数地方使用
调用形式:指明了返回类型和参数类型
不同类型的可调用对象可以共享同一调用形式。
例如
函数表:存储指向可调用对象的指针
考虑使用map实现
可用于不同元素/容器类型
算法运行于迭代器之上,不会执行容器操作。所以算法不会直接添加或者删除元素。
由于算法可以依靠迭代器完成大部分的操作,所以并不需要依靠容器的类型;但是依赖元素类型提供的操作。
大多数标准库算法对2个迭代器(第2个为尾后迭代器)表示的范围进行操作。
插入算法都假定具有足够空间
对于list和forward_list应优先使用成员函数版本CP369
命名规范
一些算法允许通过重载传递谓词
_if代表函数使用谓词来代替元素值
_copy代表将处理结果写入到额外的目的空间(同时写回输入序列)
形参形式
Func(beg,end,other args); Func(beg,end,dest,other args);//dest:指定目的位置 Func(beg,end,beg2,other args); Func(beg,end,beg2,end2,other args);//从beg2开始的空间至少和beg,end一样大
只读算法:
如果算法只访问并不改变元素,建议使用cbegin()和cend()
对于操作2个序列的算法:
序列的容器类型可以不填
用单一迭代器表示第2个序列编译器假定第2个序列和第1个序列一样长。
find
find_if:寻找第一个具有某种特征的值
接收3个参数
第3个参数为谓词
不存在时返回尾后迭代器
accumulate:求和
接收3个参数
第3个参数为和的初值,决定加法运算符的类型和返回类型
序列中的元素类型必须能和第3个参数的类型匹配,并定义了+运算符
equal:比较序列是否相同
接收3个参数
第3个参数为第2个序列的首元素
只写算法:
确保原大小必须等于/大于算法写入的元素数目
编译器假定有足够的空间,不会进行检查
fill:将给定的值赋给序列中的每个元素
接收3个参数
第3个参数被赋值的元素
fill_n
fill_n(dest,n,val)//将从dest开始的n个元素变为val
copy
接收3个参数
第3个参数表示目的序列的起始位置
必须确保目的序列的容量
返回目的迭代器之后的值
int a1[]={0,1,2,3,4}; //保证大小一致 int a2[sizeof(a1)/sizeof(*a1)]; //将a1拷贝给a2 auto ret=copy(begin(a1),end(a1),a2);
replace:将序列中指定的值都替换成新值
接收4个参数
第3个参数表示需要替换的值
replace_copy:将改变后的原序列的备份保存到别的地方
相比replace额外接收第3个迭代器参数指出保存位置
replace_copy( list.cbegin(),list.cend(), back_inserter(ivec),0,42 );
这里写代码片
排序算法
sort
unique:将重复的元素放在输入序列的最后,返回指向非重复序列之后的迭代器
void fun(vector<string> &word) { sort(words.begin(),words.end()); auto end_unique=unique(words.begin(),words.end()); words.erase( end_unique,words.end() ); }
5标准库允许算法提供自己定义的操作来代替运算符
谓词:
返回值可作为条件的表达式
一元谓词:接收1个参数
二元谓词:接收2个参数
例如
//二元谓词 bool isShorter(const string &s1,const string &s2) { return s1.size()<s2.size(); } sort( words.begin(),words.end(),isShorter ); //该算法保持相等元素的原有顺序 //在此例中相等为长度相同 stable_sort( words.begin(),words.end(),isShorter );
可调用对象:可以使用(args)(调用运算符)
函数:适用于在多个地方重复使用
函数指针
重载调用运算符的类
如果类定义了调用运算符,则该类对象称作函数对象。
例如
struct absInt{ int operator(){int val}const{ return val<0?-val:val; } }; int i=-42; absInt absobj; //可以像使用函数一样调用该类的对象 int ui=absobj(i);
标准库的函数对象CP510:可以代替运算符
可用于泛型算法的实参
stable_sort(words.begin(),words.end(),Shortstring());
lambda表达式:适用于只需要在少数地方使用
调用形式:指明了返回类型和参数类型
不同类型的可调用对象可以共享同一调用形式。
例如
//虽然执行了不同的算术运算 int add(int i,int j){ return i%j; } auto mod=[]{int i,int j}{ return i+j; }
函数表:存储指向可调用对象的指针
考虑使用map实现
map< string,function<int(int,int)> > binops; /*实际存储的是指针(不是函数指针),无法分辨重载函数。考虑输入函数指针或者lambda CP513*/ binops.insert( {"+",add} ); binops["+"](10,5);//指针指向add函数并传入参数
相关文章推荐
- C++泛型算法的一些总结
- c++实现vector类,并有一个排序和一个查找的泛型算法
- c++ 泛型算法 使用方法总结
- C++标准泛型算法库的函数为什么设计成不能改变容器大小?
- STL库中几种容器及迭代器的使用
- 本科教育忽略的黄金C++<5> 泛型算法-特定容器算法
- 泛型算法
- Essential C++学习第三章 泛型编程风格 STL
- 重拾C++ 泛型算法
- 泛型算法
- 【C++ Primer 学习笔记】: 容器和算法之【泛型算法】
- 泛型算法例子
- C++Primer第五版 第十章习题答案(1~10)
- C++Primer第五版 第十章习题答案(11~20)
- 【转】STL算法-合并(集合)
- C++初学,泛型算法 一
- c++ primer 读书笔记之第十章 泛型算法
- C++ Primer阅读心得(第十章、第十一章)
- 泛型算法与容器的关系
- Lambda 表达式使用介绍