c++Primer第十章:泛型算法(包含各种迭代器)
目录
- 算法概览
- 定制
- 谓词
- lambda表达式
- 格式
- 捕获列表
- 参数绑定
- 格式
- 插入迭代器
- iostream 迭代器
- istream_iterator
- ostream_iterator
- 反向迭代器
算法概览
一般都在algorithm,或者
算法 | 使用 |
---|---|
auto r = find(begin,end,val) | val:要查找的值,找不到返回end() |
auto sum = accumulate(begin,end,0) | 0是初始值,可以换为string(""); |
equal(L1.begin,L1.end,L2.begin) | L2中的元素数目>=L1中元素数目,L1与L2做比较,如果全部相等就true,位置必须一一对应,逆序不行 |
fill(vec.begin,vec.end,0) | 填充初始值,0可以修改,但是初始不可为空 |
fill_n(l.begin,n,0) | 明确填充数量,l的大小 |
vector< int > vec fill_n(back_insert(vec),n,0) | 插入迭代器,赋值后都会自动调用push_back |
auto ret = cpoy(l1.begin,l1.end,l2) | 注意l2的大小,返回最后一个插入元素之后的位置,即当l1.size()=l2.size(),ret是l2的尾元素之后的位置 |
repalce(l.begin,l.end,0,42) | 所有等于0的值换成42 |
repalce_copy(l.begin,l.end,back_insert(vec),0,42) | vec是调整后序列的保存位置,保留了原序列 |
sort(begin,end) | 排序 |
auto end_unique = unique(words.begin,words.end) | 需要先进行排序,返回不重复范围末尾的迭代器,不会真正的删除元素,可以使用earse按照ret进行删除 |
stable_sort(begin,end,isShorter) | 相同长度的元素按照字典序 |
auto it = find_if(begin,end,谓词) | 返回第一个使谓词为真的元素,如果不存在,返回尾迭代器 |
for_each(begin,end,操作) | 访问每个数据,并进行操作,具体看下面 |
remove_if(begin,end,谓词) | 删除 |
remove_copy_if(v1.begin,v1.end,back_inserter(v2),谓词) | v1不变,v2中都是使谓词为false的值 |
lst.merge(lst2) | |
lst.merge(lst2,comp) | |
lst.remove(val) | 会删除指定元素 |
lst.remove(一元谓词) | |
lst.reverse() | |
lst.sort() | |
lst.sort(comp) | |
lst.unique() | 会删除指定元素 |
lst.unique(pred) | 二元谓词 |
lst.splice ( iterator position, list<T,Allocator>& x ); | 将所有的数据移向指定位置之前。_after是之后 |
void splice ( iterator position, list<T,Allocator>& x, iterator it ); | 将 list x 中的由迭代器it指向的元素移到position处。_after是it之后的元素 |
void splice ( iterator position, list<T,Allocator>& x, iterator first, iterator last ); | 将 list x 中的从迭代器 first 到迭代器 last 这一段元素移动到position处 |
定制
谓词
二元谓词
bool isShorter(const string &s1,const string &s2){return s1.size()>s2.size();
}
lambda表达式
格式
[捕获参数] (参数列表) ->返回值类型 {函数体}
可以忽略参数列表和返回值类型,但是捕获参数和函数体不能省略
auto f = []{return 42;}
重写isShorter函数
[] (const string &s1,const string &s2){return a.size()<b.size();}
使用表达式
stable_sort(begin,end,[] (const string &s1,const string &s2){return a.size()<b.size();})
捕获列表
lambda 只有在其捕获列表中捕获它所在函数中的局部变量,才能在函数体中使用该变量。但是可以直接使用局部静态变量
[sz] (const string &s) {return s.size()>sz;}
for_each算法
打印数据每个数据后面跟一个空格
for_each(begin,end,[](const strong &s){cout<<s<<" ";});
整合的代码
void elimDups(vector<string> &words){stable_sort(words.begin(),words.end(),[](const string &s1,const string &s2){return s1.size()<s2.size();});auto end_unique = unique(words.begin(),words.end());// while(end_unique!=words.end()){// end_unique = words.erase(end_unique);// end_unique++;// }words.erase(end_unique,words.end());
}void biggies(vector<string> &words,vector<string>::size_type sz){elimDups(words);auto wc = find_if(words.begin(),words.end(),[sz](const string &s){return s.size()>sz;});auto count = words.end() - wc;cout<<"count="<<count<<endl;for_each(wc,words.end(),[](const string &s){cout<<s<<" ";});cout<<endl;
}vector<string> vs{"sadsad","daddv","sa","rffdsvfegt","sda","addvgwe","dsadsadas","q","sadsad","daddv","sa","rffdsvfegt"};
biggies(vs,5);
结果
- 值捕获
在lambda表达式创建时创建拷贝
int v=41;
auto f = [v1]{return v1};
v1=10;
auto j = f();//j=41
2.引用捕获
int v=41;
auto f = [&v1]{return v1};
v1=10;
auto j = f();//j=10
ostream流只能使用引用捕获
ostream &os=cout;
for_each(words.begin(),words.end(),[&os,c](const string &c){os<<s<<c;});
3.隐式捕获
[&,identifier_list],identifier_list是值捕获
[=,identifier_list],identifier_list是引用捕获
4.修改捕获的值
效果和刚刚一样,外部值改变不影响表达式;
v=42
[v] () mutable {return ++v;}
v=0;
调用之后v=43
外部值改变会影响表达式
[&v] () mutable {return ++v;}
v=0;
调用之后值为1;
5.注意lambda表达式的返回值,条件运算符不用操心。
参数绑定
格式
bind只能拷贝参数
auto newCallable = bind(callable,arg_list);
使用案例
_1表示占位符
auto check6 = bind(check_size,_1,6);
string s="hello";
bool b = check6(s);
//就不需要值捕获了
auto wc = find_if(words.begin(),words.end(),bind(check_size,_1,sz));
重排参数顺序
从小到大->从大到小
bool isShorter(const string &s1,const string &s2)
{...}
sort(begin,end,bind(isShorter(_2,_1)))
bind捕获os,使用ref,传递一个对象但是不拷贝
for_each(words.bigen(),words.end(),bind(print,ref(os),-1,' '));
插入迭代器
项目 | Value |
---|---|
back_inserter | 创建一个使用push_back的迭代器 |
front_inserter | 创建一个使用push_front的迭代器 |
inserter | 插入给定元素之前 |
代码
it = c.insert(it,val);
++it;指向原来的元素
list<int> l1{1,2,3,4};
list<int> lst2,lst3;
copy(l1.cbegin(),l1.cend(),front_inserter(lst2));
//st2={4,3,2,1};
copy(l1.cbegin(),l1.cend(),inserter(lst3,lst3.begin()));
//lst3={1,2,3,4};
iostream 迭代器
istream_iterator
项目 | Value |
---|---|
istream_iterator< T > in(is) | in从输入流is读取类型为T的值 |
istream_iterator< T > end | 表尾后位置 |
使用流从标准输入读取数据
istream_iterator<int> in_it(cin);
istream_iterator<int> in_eof;
vector<int> vec;
while (in_it!=in_eof)
{vec.push_back(*in_it++);
}
for(auto e:vec)cout<<e<<" ";
cout<<endl;
//vector<int> vec(in_iter,eof)
结果
使用流读取文件
vector<string> vec_str;
cout<<"start"<<endl;
ifstream input ("text.txt");
istream_iterator<string> str_it(input);
if(!input){cout<<"no such file"<<endl;return 0;
}
istream_iterator<string> str_eof;
cout<<*str_it<<endl;
while(str_it!=str_eof){vec_str.push_back(*str_it++);
}
cout<<vec_str.size()<<endl;
for(auto e: vec_str){cout<<e<<" ";
}
cout<<endl;
if(input.is_open()){cout<<"close file"<<endl;input.close();
}
结果
ostream_iterator
项目 | Value |
---|---|
ostream_iterator< T > out(os) | out将值写到输出流os |
ostream_iterator< T > out(os,d) | out将值写到输出流os,每个值后面带个d |
out = val | 使用<<运算符将val写入到out所绑定的ostream中 |
代码
vector<string> vs{"sadsad","daddv","sa","rffdsvfegt","sda","addvgwe","dsadsadas","q","sadsad","daddv","sa","rffdsvfegt"};ostream_iterator<string> out_iter(cout," ");for(auto e:vs){*out_iter = e;out_iter++;}
结果
使用流处理类类型
不知道怎么回事out_iter有问题,老是类型不匹配,有没有大佬可以看一下怎么回事吗
istream_iterator<sales_data> item_iter(cin),eof;ostream_iterator<sales_data> out_iter(cout," ");sales_data sum = *item_iter++;// while(item_iter!=eof){// if(item_iter->isbn()==item_iter->isbn()){// // sum = sum + *item_iter;// // item_iter++;//读取下一条记录// sum += *item_iter++; // }// else{// out_iter = sum;// sum += *item_iter++; // // sum = *item_iter;// // item_iter++;//读取下一条记录// }// }//out_iter = sum;
反向迭代器
逆序
sort(v.rbegin(),v.rend());
使用.base转换反向迭代器为普通迭代器
auto rcomma = find(line.crbegin,line.crend(),',');
cout<<string(rcomma.base(),line.end());
c++Primer第十章:泛型算法(包含各种迭代器)相关推荐
- C++primer第十章 泛型算法 10.1 概述 10.2 初识泛型算法
大多数算法都定义在头文件algorithm中.标准库还在头文件numeric中定义了 一组数值泛型算法 一般情况下,这些算法并不直接操作容器,而是遍历由两个迭代器指定的一个元素范围(参见9.2.1节, ...
- C++primer第十章 泛型算法 10.4 再探迭代器 10.5 泛型算法结构
除了为每个容器定义的迭代器之外,标准库在头文件iterator中还定义了额外几种迭代器.这些迭代器包括以下几种. 插入迭代器(insert iterator):这些迭代器被绑定到一个容器上,可用来向容 ...
- C++ primer 第十章 泛型算法
目录 10.1 初识泛型算法 10.1.1 只读算法 10.1.2 写容器算法 10.2 定制操作 10.2.1 lambda表达式 10.2.2 lambda捕获和返回 10.3 再探迭代器 10. ...
- C++primer第十章 泛型算法 10.3 定制操作
10.3定制操作 很多算法都会比较输入序列中的元素.默认情况下,这类算法使用元素类型的<或==运算符完成比较.标准库还为这些算法定义了额外的版本,允许我们提供自己定义的操作 来代替默认运算符. ...
- C++ Primer 学习笔记 第十章 泛型算法
C++ Primer 学习笔记 第十章 泛型算法 336 find函数 #include <iostream> #include <vector> #include <s ...
- 《C++ Primer 5th》笔记(10 / 19):泛型算法
文章目录 概述 算法如何工作 迭代器令算法不依赖于容器 但算法依赖于元素类型的操作 关键概念:算法永远不会执行容器的操作 初识泛型算法 只读算法 算法和元素类型 操作两个序列的算法 写容器元素的算法 ...
- 泛型算法----概述,初识泛型算法,定制操作
一.概述 标准库定义了一组泛型算法:称它们为"算法",是因为它们实现了一些经典算法的公共接口,如排序和搜索:称它们是"泛型",是因为它们可以用于不同类型的元素和 ...
- 泛型算法(lambda表达式、function类模板、bind函数适配器、迭代器类别、链表数据结构独有的算法)
文章目录 概念 find()函数 迭代器令算法不依赖于容器 但算法依赖于元素类型的操作 算法永远不会执行容器的操作 只读算法 accumulate()函数 从两个序列中读取元素(equal函数为例) ...
- 泛型算法STL中的迭代器,泛型算法,萃取机的一个实现案例
迭代器介绍: 迭代器其实是一个类,但是因为重载了* ++等指针操作的符号,所以有着和指针类似的共能,对于一个自己写的类,如果想使用迭代器这种功能就得自己写了,STL的标准容器都有迭代器,迭代器作用于, ...
- C++ primer 第10章 泛型算法
文章目录 概述 find count 初识泛型算法 只读算法 只读算法accumulate 只读算法equal 写容器元素的算法 算法fill 算法fill_n back_inserter 算法cop ...
最新文章
- ICLR20 | GraphZoom:可缩放图嵌入
- leetcode 367. Valid Perfect Square
- 基于高阶累积量的数字调制信号分类(Hierarchical Digital Modulation Classification Using Cumulants例1复现)
- 解决:Access denied for user ‘root‘@‘localhost‘ (using password: YES)
- 共阳数码管段码表_C51编程7数码管显示原理
- 京东健康携手国控湖北 首批1500万只口罩专供湖北
- FISCO BCOS 智能合约库 应用
- Luogu1501[国家集训队] Tree II
- 敏捷开发模式下SDL实践
- IE8补充前后缀快捷键
- 1.学生党如何查找文献书籍
- 最全的 JVM 面试知识点(二):垃圾收集
- ubuntu 保存视频流的关键
- 控制翻页c语言,阅读器多种翻页的设计与实现
- 树模型(一):预备知识
- java实现单一登录 踢人效果
- 「BJOI 2019」奥术神杖
- 求俩向量角度 允许超过180度 python
- 高级电子技能及生产工艺流水线实训台QY-GY01A
- python分析北京租房现状,最后的价格分布地图亮了
热门文章
- 《麻省理工科技评论》在京举办第二届 EmTech China 峰会,全球顶级科技头脑打造年度最强话语场
- 第一期 android源码集合987个实例(从网上摘抄,在此记录下)
- 搜索全部mp3类型文件
- Windows sshfs挂载远程文件夹
- 北大青鸟汉字注释机内码_北大青鸟11SF主机调试软件里面的,汉字注释,联动逻辑,总线对应,191层显注释,291层显注释...
- 终于官宣了!OPPO R15在手机屏幕上又有新突破
- 函数指针与block
- 腾讯测试“过来人”告诉你,到达瓶颈期如何提升自己
- 题解 P4388 【付公主的矩形】
- C# winform 实现PDF文件阅读