c++ primer第10章
来源:互联网 发布:asap2020软件 64bit 编辑:程序博客网 时间:2024/06/05 17:57
1 概述
标准库没有给每个容器提供大量的功能,而是提供了一组算法,这些算法大部分独立于特定的容器。这些算法是通用的:他们可以用于不同类型的容器和不同类型的元素。
泛型算法:一些经典算法的公共接口,用于不同类型元素、多种容器类型的排序、搜索。
头文件:algorithm
这些算法一般,遍历由两个迭代器指定的一个元素范围来操作:
auto result = find(vec.cbegin(),vec.cend(),42);
算法不会影响容器的大小,不会删除、添加元素,及算法不能执行容器操作;
2 初识泛型算法
2.1 accumulate()求和:
计算两个迭代器之间元素的和,第三个参数是初始值;定义的“+”运算的类型,都可以使用accumulate函数;
//算术求和
vector <int> venc;
int sum = accumulate(venc.cbedin(),venc.cend(),0);
//连接字符串
vector <string> v;
string sum = accumulate<v.cbegin(),v.cend(),string(" ") );
2.2 equal() 求等长类型相等否
equal(roster1.cbegin(), roster1.cend(),roster2.cbegin() );
roster1.cbegin(), roster1.cend(): 表示一个序列;
roster2.cbegin():第二个序列的首元素;
注意:
1 两个序列类型可以不一样,只要能用 == 比较就行;
2 算法假设两个序列一样长,在第二个序列中取出相同长度和一序列比较;
2.3 fill() 、fill_n()写容器
fill(venc.begin(),venc.end(),0 ); //将迭代器范围的值设为0;
fill_n(venc.begin(),venc.size(),0) //所有元素重置为0;
fill_n(dest.begin(), n ,val) //dest的前n个重置为cal;
2.4 copy()拷贝算法
2.5 replace()替换序列某元素
replace(ilst.begin(),ilst.end(),0,42); //将所有的 0 改为 42;
2.6 replace_copy()拷贝替换
2.7 sort()排序
sort(word.begin(),word.end()):范围内从小到大排序;
unique(word.begin(),word.end()):一般用于sort排序后的序列,将重复的元素排在后面,返回第一个重复元素所在位置;
sort(histVector.begin(), histVector.end(), greater<float>());
上述例子中系统自己为sort提供了less仿函数。在STL中还提供了其他仿函数,以下是仿函数列表:
名称
功能描述
equal_to
相等
not_equal_to
不相等
less
小于
greater
大于
less_equal
小于等于
greater_equal
大于等于
3 定制操作
标准库,允许我们提供资金定义的操作;如sort()的方向排序;
3.1 向算法传递函数
sort的重载版本有第三个参数,其是谓词(只接受一个或者两个参数)
按照长度从短到长排序words
sort(words.begin(),words.end(),isShorter);
stable_wort(words.begin(),words.end(),isShorter); //长度从短到长,相等大小的,按字母表顺序排;
elimDup(words); //将words按字典排序,删除重复单词;
//用partition()函数,第三个谓词参数为真的排在前面,为假的排在后面,返回第一个为假的
#include <iostream>#include <string>#include <vector>#include <algorithm>//! Predicateinlinebool isLongerThan5(const std::string &s){ return s.size() >= 5;}void partition_words(std::vector<std::string> &v){ auto iter_longerLast = std::partition(v.begin(), v.end(), isLongerThan5); //! @note the range to be printed not whole of the v, so can't use for range. for(auto it = v.begin(); it != iter_longerLast; ++it) std::cout << *it << " "; std::cout << std::endl;}int main(){ std::vector<std::string> v{"a","as","aasss","aaaaassaa","aaaaaabba","aaa"}; partition_words(v); return 0;}
3.2 lambda 表达式
可调用对象有:函数、指针、重载了函数调用运算符的类、lambda表达式;
lambda表达式,表示一个可调用的代码单元。
与任何函数类似,一个lambda具有一个返回类型、一个参数列表、一个函数体;
lambda可能定义在函数内部;
- [captures] (params) -> ret {Statments;}
注释:[capturne]方括号中的数是另外包含进去的可使用的数;
//sort()排序、enique()再排序、vs.erase()删除重复、stable_sort()大小字幕表排序、find_if()找到第一个大小为3的、for_each打印每个大于等于三的;
auto wc = std::find_if(vs.begin(), vs.end(),[sz](string const& s){ return s.size() >= sz; }); std::for_each(wc, vs.end(), [](const string &s){ std::cout << s << " "; });
//找出vector<strig> 中,所有size()大于3的字符串,并输出,不可重复;//
#include <iostream>#include <string>#include <vector>#include <algorithm>//! from ex 10.9void elimdups(std::vector<std::string> &vs){ std::sort(vs.begin(), vs.end()); auto new_end = std::unique(vs.begin(),vs.end()); vs.erase(new_end, vs.end());}//! ex10.18void biggies_partition(std::vector<std::string> &vs, std::size_t sz){ elimdups(vs); auto pivot = partition(vs.begin(), vs.end(),[sz](const std::string &s){ return s.size() >= sz;} ); for(auto it = vs.cbegin(); it != pivot; ++it) std::cout << *it << " ";}//! ex10.19void biggies_stable_partition(std::vector<std::string> &vs, std::size_t sz){ elimdups(vs); auto pivot = stable_partition(vs.begin(), vs.end(),[sz](const std::string& s){ return s.size() >= sz; }); for(auto it = vs.cbegin(); it != pivot; ++it) std::cout << *it << " ";}int main(){ //! ex10.18 std::vector<std::string> v{ "the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle" }; std::cout << "ex10.18: "; std::vector<std::string> v1(v); biggies_partition(v1,4); std::cout << std::endl; //! ex10.19 std::cout << "ex10.19: "; std::vector<std::string> v2(v); biggies_stable_partition(v2,4); std::cout << std::endl; return 0;}3.3 lambda值捕获:
#include <iostream>#include <string>#include <vector>#include <algorithm>using std::vector;using std::count_if;using std::string;//! Exercise 10.20std::size_t bigerThan6(vector<string> const& v){ return count_if(v.cbegin(), v.cend(), [](string const& s){ return s.size() > 6; });}int main(){ //! ex10.20 vector<string> v{ "alan","moophy","1234567","1234567","1234567","1234567" }; std::cout << "ex10.20: " << bigerThan6(v) << std::endl; //! ex10.21 int i = 7; auto check_and_decrement = [&i](){ return --i ? false : true; }; std::cout << "ex10.21: "; while(!check_and_decrement()) std::cout << i << " "; std::cout << i << std::endl; return 0;}//! output ://!//ex10.20: 4//ex10.21: 6 5 4 3 2 1 0
3.4 参数绑定
//统计长度大于等于6的个数
#include <iostream>#include <vector>#include <string>#include <algorithm>#include <functional>using std::string;using namespace std::placeholders;bool isBiggerThan6(const string &s, string::size_type sz){ return s.size() > sz;}int main(){ std::vector<string> authors{"Mooophy", "pezy", "Queequeg90", "shbling", "evan617"}; std::cout << count_if(authors.cbegin(), authors.cend(), bind(isBiggerThan6, _1, 6));}// @Out// 4
4 再探迭代器
4.1 插入迭代器
std::unique_copy(vec.begin(), vec.end(), back_inserter(lst)); //无重复的拷贝;
4.2 iostream迭代器
4.2.1 istream_iterator迭代器
stream_iterator<int> in_iter(cin); //
stream_iterator<int> eof; //定义为空,从而可当作尾后迭代器来使用。
4.2.2 ostream_iterator
//读入一个文本,将其存入vector<string>中,并输出#include <iostream>#include <fstream>#include <vector>#include <string>#include <iterator>using std::string;int main(){ std::ifstream ifs("../data/book.txt"); std::istream_iterator<string> in(ifs), eof; std::vector<string> vec; std::copy(in, eof, back_inserter(vec)); // output std::copy(vec.cbegin(), vec.cend(), std::ostream_iterator<string>(std::cout, "\n"));}//读入数列,并排序无重复输出#include <iostream>#include <vector>#include <algorithm>#include <iterator>int main(){ std::istream_iterator<int> in_iter(std::cin), eof; std::vector<int> vec; while (in_iter != eof) vec.push_back(*in_iter++); std::sort(vec.begin(), vec.end()); std::unique_copy(vec.cbegin(), vec.cend(), std::ostream_iterator<int>(std::cout, " "));}
4.4 反向迭代器
//寻找并打印第一个单词auto comma=find(line.begin(),line.end(),',');cout<<string(line.begin(),comma)<<endl;//选择并打印最后一个单词auto rcomma=find(line.rbegin(),line.rend(),',');cout<<string(rcomma.base(),line.end());//将v的3到7之间的数,逆序拷贝到I中; std::copy(v.crbegin() + 3, v.crbegin() + 8, std::back_inserter(l));
5 泛型算法结果
6 特定容器算法
- C++Primer习题第10章
- C++Primer第5版读书笔记(第10章)
- [C/C++] 第12章 类 primer
- C primer plus第10章(指针)习题
- C++Primer第10章关联容器习题
- C++Primer 第10章的练习题:TextQuery类
- 【C++primer学习笔记】第10章 关联容器
- c primer plus第10章总结:数组和指针
- C++primer plus第9-10章笔记
- C++Primer(第10章课后程序题源代码)
- C.Primer.Plus(第六版)第10章 编程练习
- 《C Primer Plus(第5版)中文版》第7章编程练习第10题
- C++Primer 读书笔记 第1章 开始
- C++Primer 读书笔记 第2章 浏览
- 看完C++Primer第7章,第一遍
- c primer plus第14章习题
- C++Primer第6章学习笔记
- C++primer第9章习题解答
- Mybatis-03-配置文件及Mybatis主要API详解
- rapidjson串组装的代码示例
- 实现自己的仿真小车移动
- Android文本输入框EditText属性和方法说明
- 软考学习-二进制转化
- c++ primer第10章
- Spring知识整理【二】Spring 环境搭建
- 混合编程--fortran调用C++采用ODBC形式连接MYSQL数据库
- GCD and LCM HDU
- pip install 出现报asciii码错误的问题
- ARP协议详解
- 【已解决】R语言添加行、列,转置操作
- rtos开发总结
- LeetCode #79