大多数算法定义在头文件algorithm中,在头文件numeric中定义了数值泛型算法。

以find算法为例:在容器的两个迭代器指定的范围内遍历,查找特定值。

int val=; auto result=find(ivec.begin(),ivec.end(),val); cout<<result<<endl;

迭代器令算法不依赖于容器,但算法依赖于元素类型的操作

算法不执行容器的操作,只会执行迭代器的操作

只读算法

  只会读取其范围之内的元素而不会改变元素

  除了find算法之外,例如accumulate算法(定义在numeric头文件中),返回范围内元素之和+指定初值

    cin>>sum;

    accumulate(ivec.cbegin(),ivec.cend(),sum);(如果是string类型,则是将string连接起来)

  对于只读算法,最好选取cbegin和cend作为迭代器

  再举操作两个序列的算法equal为例:(如果两个序列所有对应元素相同,则返回true,否则返回false)

    equal(ivec1.cbegin(),ivec1.cend(),ivec2.cbegin());

  equal算法并不要求两个序列元素类型严格一致,只要能用==比较即可

  基于此例,对于只给出第二个序列的单一迭代器的算法,都假定两序列等长(至少不能比第一个短)

写元素算法

  需要确保容器自身大小至少不小于写入的元素数目(因为算法不能改变容器大小)

   例如:fill(ivec.begin(),ivec.end(),val);将容器每个值赋为val

     fill_n(ivec.begin(),ivec.size(),val);将容器每个值赋为val

      注意:如果对空容器使用fill_n并且指定长度,会引起错误

  back_inserter(定义在iterator头文件)

    为了向容器尾部添加元素而使用的迭代器

      vector<int> ivec; auto it =back_inserter(ivec); *it=;

    这样在容器的尾部添加了一个元素,值为23

    结合fill_n使用:(添加了10个值为val的元素到ivec)

      vector<int> ivec; fill_n(back_inserter(ivec),,val);

  拷贝算法:

        auto ret=copy(begin(arr1),end(arr1),arr2);

    这样将arr1序列的值拷贝给arr2(要求arr2至少和arr1等长),返回end(arr2)

    类似copy算法,replace也具备此类替换效果:

      replace(ilst.begin(),ilst.end(),search_value,new_value);

    这样将ilst序列中所有值为search_value的元素赋值为new_value

    如果不想将原序列改变,可以将元素替换后的序列保存在其他容器中:

      replace_copy(ilst.begin(),ilst.end(),back_inserter(ivec),search_value,new_value);

    这样借助replace_copy函数和back_inserter将新的ilst保存在ivec中,原本的ilst不变

重排元素算法

  

 #include<iostream>
#include<iterator>
#include<algorithm>
#include<vector>
#include<string>
#include<cstdlib>
using namespace std;
void elimDups(vector<string> &vec){
//使向量按字典序排序
sort(vec.begin(),vec.end());
//使用unique函数重排序列,使得序列中每个词仅出现一次
//获得的序列在原序列的前部,返回不重复元素的子序列的尾后迭代器
auto end_unique=unique(vec.begin(),vec.end());
//使用erase函数删除重复单词
vec.erase(end_unique,vec.end());
}
int main(){
string str;
vector<string> svec;
while(getline(cin,str)){
svec.push_back(str);
}
for(const auto &i:svec){
cout<<i<<" ";
}
elimDups(svec);
cout<<endl;
for(const auto &j:svec){
cout<<j<<" ";
} }
/*output:
the
quick
red
fox
jumps
over
the
slow
red
turtle
^Z
the quick red fox jumps over the slow red turtle
fox jumps over quick red slow the turtle*/

定制操作

  例如使sort接受第三个参数,此参数即为谓词(可调用的表达式,返回值可作为条件),原本sort利用<来比较元素,那么这里使用谓词来代替<作为比较的依据

  

 bool isShorter(const string &s1,const string &s2){
return s1.size()<s2.size();}
sort(svec.begin(),svec.end(),isShorter);

  这里用长度来比较字符串,而不是以字典序作为比较依据

  如果我们希望将等长的字符串以字典序比较,不等长的字符串以长度比较:

 void elimDups(vector<string> &vec){
//使向量按字典序排序
sort(vec.begin(),vec.end());
//使用unique函数重排序列,使得序列中每个词仅出现一次
//获得的序列在原序列的前部,返回不重复元素的子序列的尾后迭代器
auto end_unique=unique(vec.begin(),vec.end());
//使用erase函数删除重复单词
vec.erase(end_unique,vec.end());
}
int main(){
elimDups(svec);
stable_sort(svec.begin(),svec.end(),isShorter);
}

  这里使用了提供谓词的stable_sort函数,保持了等长的元素之间的字典序

  lambda表达式:(c++11)格式:[capture list](parameter list)->return type{function body};

    这里capture list是函数中定义的局部变量的列表(通常为空)

    建立调用对象时可以省略列表 (相当于参数为空)和返回类型(除非函数体中存在返回语句,否则默认为void),如:

      auto f = [ ]{return ;};   f();

    不同于普通函数,lambda不能有默认参数

    例如:等价于上述isShorter函数的lambda:

[](const string &s1,const string &s2){  return s1.size()<s2.size();}

    [ ]内为空说明lambda不使用函数内任何局部变量

    如果capture list 不为空,则函数体可以使用capture list中的变量:

     [sz](const string&s1){ return s1.size()<sz;};

    完整的biggies函数:包含find_if函数和for_each函数

 void biggies(const string &s1,const string::size_type sz){
elimDups(svec);
stable_sort(svec.begin(),svec.end(),[](const string &s1,const string &s2){
return s1.size()<s2.size();});
auto wc=find_if(svec.begin(),svec.end(),[sz](const string &s){
return s.size()>=sz});
auto count = svec.end()-wc;
for_each(wc,svec.end(),[](const string &s){cout<<s<<' ';});
}

    这里find_if函数返回指向第一个长度不小于给定参数sz的元素的迭代器

    这里for_each函数接受一个可调用对象,并输出序列中每个元素调用此对象

   lambda的捕获和返回

    每当定义一个lambda时,编译器自动生成一个未命名的类类型,

    每当向函数传递一个lambda,同时定义了一个新类型和该类型的一个对象。

    与函数调用参数类似,lambda的capture list可以是值捕获也可以是引用捕获(其效应与函数参数别无二致)

    (注意:应尽量避免引用捕获或者指针捕获,如果必须如此,必须确保在调用lambda的时期内捕获的对象的值是有效的)

    与显式捕获相对应的,也可以使用隐式捕获:

    [=]表示隐式的值捕获,[&]表示隐式的引用捕获

    [=,&]表示按照调用顺序,第一个是值捕获,第二个是引用捕获(其余组合以此类推)

     可变lambda

    如果希望能够改变被捕获的变量的值,必须在参数列表首加上关键字mutable

     auto f = [sz] () mutable{return ++sz;}; 可变lambda的参数列表可以省略

   指定lambda返回类型

    例如: transform(ivec.begin(),ivec.end(),ivec.begin(),[](int i)->int{return i<?i:-});  

    这里transform函数将原序列各个元素的值替换为其绝对值(第一个和第三个参数相同==调用和输入序列首是同一位置)

以上说明了lambda的使用方法,一般较为简单的操作适合使用lambda,如果是比较复杂而且重复的操作还是调用函数比较合适

参数绑定

  标准库bind函数:(c++11)(所在头文件functional)

    如果我们写了一个函数,并且希望用此函数来代替lambda,使用bind来解决向sz形参传递参数的问题

    调用bind的格式:auto newCallable=bind(callable,args_list);

    (其中args_list中如果含有诸如_1,_2之类的名字,则用来表示newCallable中对应位置的参数)

    具体使用例如:  

 bool check_size(const string &s1,string::size_type sz){
return s1.size()>=sz;}
auto check2=bind(check_size,_1,);

    这里_1表示check2的第一个参数(也是唯一一个)就是(check_size的第一个参数)const string&,2表示sz==2

    调用check2:  string str="HELL";  bool b2=check2(str);(等效于调用check_size(str,6))

    bind语句可以作为lambda的替代品

    上述的语句中如名字_1,_2之类在使用之前需要声明名字空间:using std::placeholders::_1;之类的语句

    (也可以直接写 using namespace std::placeholders;)

  bind参数与函数对应的关系:

    auto g=bind(f,a,b,_2,c,_1);

    调用g(_1,_2);等效于调用f(a,b,_2,c,_1);

    (如果调用g(X,Y)等效于调用f(a,b,Y,c,X))

  如果希望传递给bind一个引用参数parameter,必须使用ref(parameter)或者cref(parameter)

迭代器再探

  插入迭代器

    支持的操作:it = t;在it指定的位置插入值t

    back_inserter(value);创建一个使用push_back的迭代器

    front_inserter(value);创建一个使用push_front的迭代器

    inserter(value,pos);在pos迭代器之前一个位置插入值为value的元素

    

    

    

C++Primer 5th Chap10 Generic Algorithms(未完)的更多相关文章

  1. AutoMapper介绍(未完待续、部分没实现)

    实体间转换工具.其实也可以用Json来实现同名属性.异名属性(用JsonProperty指明)的自动转换 最新版本6.11 需要使用vs2013以上.vs2012下载新版 nuget会遇到问题.只能旧 ...

  2. java泛型基础、子类泛型不能转换成父类泛型--未完待续

    参考http://how2j.cn/k/generic/generic-generic/373.html 1.使用泛型的好处:泛型的用法是在容器后面添加<Type>Type可以是类,抽象类 ...

  3. javascript有用小功能总结(未完待续)

    1)javascript让页面标题滚动效果 代码如下: <title>您好,欢迎访问我的博客</title> <script type="text/javasc ...

  4. ASP.NET MVC 系列随笔汇总[未完待续……]

    ASP.NET MVC 系列随笔汇总[未完待续……] 为了方便大家浏览所以整理一下,有的系列篇幅中不是很全面以后会慢慢的补全的. 学前篇之: ASP.NET MVC学前篇之扩展方法.链式编程 ASP. ...

  5. 关于DOM的一些总结(未完待续......)

    DOM 实例1:购物车实例(数量,小计和总计的变化) 这里主要是如何获取页面元素的节点: document.getElementById("...") cocument.query ...

  6. 我的SQL总结---未完待续

    我的SQL总结---未完待续 版权声明:本文为博主原创文章,未经博主允许不得转载. 总结: 主要的SQL 语句: 数据操作(select, insert, delete, update) 访问控制(g ...

  7. virtualbox搭建ubuntu server nginx+mysql+tomcat web服务器1 (未完待续)

    virtualbox搭建ubuntu server nginx+mysql+tomcat web服务器1 (未完待续) 第一次接触到 linux,不知道linux的确很强大,然后用virtualbox ...

  8. MVC丶 (未完待续······)

         希望你看了此小随 可以实现自己的MVC框架     也祝所有的程序员身体健康一切安好                                                     ...

  9. 一篇文章让Oracle程序猿学会MySql【未完待续】

    一篇文章让Oracle DB学会MySql[未完待续] 随笔前言: 本篇文章是针对已经能够熟练使用Oracle数据库的DB所写的快速学会MySql,为什么敢这么说,是因为本人认为Oracle在功能性方 ...

随机推荐

  1. video标签在浏览器不能使用的问题 ?

    之前video标签是可以用的,但是压缩之后在移动端可以用,在pc浏览器不可以用? 怎么解决? 这样的写法会报错  说是缺乏source  但是你加上source也没有用 <video src=& ...

  2. 数据结构Java版之堆&堆排序(九)

    堆分为大顶堆,和小顶堆. 什么是堆? 堆可以看成是一棵二叉树,二叉树的元素是一个数组不断的从左到右轮训放置.如果是大顶堆,则大的数放上面一层,小的数放下面一层.上一层的数,一定大于下一层的数.小顶堆则 ...

  3. Windows 实例远程桌面报错“没有远程桌面授权服务器可以提供许可证”

    参考阿里云帮助文档: https://help.aliyun.com/knowledge_detail/40859.html?spm=5176.10695662.1996646101.searchcl ...

  4. T-MAX组--项目冲刺(第五天)

    T-MAX组--项目冲刺(第五天) THE FIFTH DAY 项目相关 作业相关 具体描述 所属班级 2019秋福大软件工程实践Z班 作业要求 团队作业第五次-项目冲刺 作业正文 T-MAX组--项 ...

  5. qt creator中常用快捷键

    激活欢迎模式 Ctrl + 1 激活编辑模式 Ctrl + 2 激活调试模式 Ctrl + 3 激活项目模式 Ctrl + 4 激活帮助模式 Ctrl + 5 激活输出模式 Ctrl + 6 查找当前 ...

  6. Sqlmap全参数详解

    sqlmap全参数详解 sqlmap是在sql注入中非常常用的一款工具,由于其开源性,适合从个人到企业,从学习到实战,各领域各阶段的应用,我们还可以将它改造成我们自己独有的渗透利器.这款工具中,大大小 ...

  7. 20161209pod search 'fmdb'提示[!] Unable to find a pod with name, author, summary, or description matching `fmdb`

    从SVN上更新工程之后运行工程提示错误: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update y ...

  8. Windows 操作系统 快捷键

    窗口放大缩小:  + ↑↓ 最小化窗口: ALT + Esc 关闭窗口: Alt + F4 搜索功能:  + 直接输入搜索内容 打开文件管理器:  + E 在文件管理器中切换: Tab

  9. 读《中国人工智能与 IJCAI 的 40 周年,还有哪些未曾对外诉说的故事?》

    原文地址: https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_10186783044528 ...

  10. 全面系统Python3入门+进阶_汇总

    https://coding.imooc.com/class/136.html#Anchor 全面系统Python3入门+进阶-1-1 导学 全面系统Python3入门+进阶-1-2 Python的特 ...