泛型算法本身不会执行容器的操作,它们只会运行于迭代器之上,执行迭代器的操作。因此算法可能改变容器中保存的元素,也可能在容器内移动元素,但永远不会直接添加或删除元素。

只读算法:

accumulate:

 #include <iostream>
#include <algorithm>
#include <vector>
#include <list>
#include <forward_list>
#include <deque>
#include <string>
using namespace std; int main(void){
vector<int> v(, );
int sum = accumulate(v.cbegin(), v.cend(), );
cout << sum << endl;//
sum = accumulate(v.cbegin(), v.cend(), );//第三个参数是和的初始值且决定了函数中使用哪个加法运算以及返回值的类型
cout << sum << endl;//
cout << endl; list<string> l = {"fjs", "afjkflf", "wwe"};
string str = accumulate(l.cbegin(), l.cend(), string(""));//注意不能用c风格的字符串,c风格字符串上没有重载+
cout << str << endl;//fjsafjkflfwwe deque<double> q(, 1.1);
double cnt = accumulate(q.cbegin(), q.cend(), 0.0);//第三个参数决定了使用何总类型的+
double cc = accumulate(q.cbegin(), q.cend(), );
cout << cnt << endl;//
cout << cc << endl;// return ;
}

显然,只要支持随机访问(能用迭代器遍历)的容器都支持 accumulate 算法

注意:第三个参数是和的初始值且决定了函数中使用哪个加法运算以及返回值的类型

不能用c风格的字符串,c风格字符串上没有重载+

equal:

 #include <iostream>
#include <algorithm>
#include <vector>
#include <list>
using namespace std; int main(void){
vector<string> v(, "hello");
vector<string> v1(, "hello");
list<string> l1(, "hello");
list<const char*> l2 = {"hello", "hello", "hello", "hello", "zzz"};
list<const char*> l3 = {"hello", "hello", "hello", "hello", "zzz"}; bool flag1 = equal(v.cbegin(), v.cend(), l1.cbegin());//可以两个不同类型的容器之间比较,只要元素之间支持==运算符即可
bool flag2 = equal(v.cbegin(), v.cend(), l2.cbegin());
bool flag3 = equal(l2.cbegin(), l2.cend(), l3.cbegin());
// bool flag4 = equal(v.cbegin(), v.cend(), v1.cbegin());//会运行时出错,只接受一个单一的迭代器来表示第二个序列的算法,都假定第二个序列至少与第一个序列一样长
cout << flag1 << endl;//
cout << flag2 << endl;//
cout << flag3 << endl;// cout << endl; return ;
}

注意:可以两个不同类型的容器之间比较,只要元素之间支持 == 运算符即可

只接受一个单一的迭代器来表示第二个序列的算法,都假定第二个序列至少与第一个序列一样长

写容器元素的算法:

fill/fill_n:

 #include <iostream>
#include <algorithm>
#include <vector>
using namespace std; int main(void){
vector<int> v, v1, v2;//定义三个空容器
fill(v.begin(), v.end(), );
fill_n(v1.begin(), v1.size(), ); // fill_n(v2.begin(), 10, 0);//错误,v2是一个空容器,越界了
v2.reserve();//给v2分配5个int的空间
fill_n(v2.begin(), , );//v2虽然分配了空间,但其仍然是一个空容器,不改变容器大小无法向其中赋值
cout << v2.size() << endl;//
cout << v2.capacity() << endl;//
return ;
}

注意:使用 fill_n 第一个元素传入一个普通迭代器时如果我们第二个参数不传 v.size() 的话很容易导致越界

fill_n 本身不改变容器的大小,若传给 fill_n 的第一个迭代器是一个普通迭代器的话无法给空容器赋值

back_inserter:

 #include <iostream>
#include <iterator>
#include <vector>
using namespace std; int main(void){
vector<int> v1;//空向量
auto it = back_inserter(v1);
//back_inserter接受一个指向容器的引用,返回一个与该容器绑定的插入迭代器,当我们通过此迭代器赋值时,
//赋值运算会调用push_back将一个具有给定值的元素添加到容器中
*it = ;//此时v1中有一个元素0
for(const auto indx : v1){
cout << indx << endl;
} vector<int> v2(, );
*back_inserter(v2) = ;
for(const auto indx : v2){
cout << indx << " ";
}
cout << endl;//1 1 1 1 0 vector<int> v3;
fill_n(back_inserter(v3), , );//添加10个0到v3中
for(const auto indx : v3){
cout << indx << " ";
}
cout << endl;//0 0 0 0 0
return ;
}

注意:back_inserter 接受一个指向容器的引用,返回一个与该容器绑定的插入迭代器,当我们通过此迭代器赋值时,赋值运算会调用 push_back 将一个具有给定值的元素添加到容器中

fill_n 算法本质是对传入的迭代器的操作,所以给 fill_n 传入普通迭代器时不能改变对应容器的大小,若 fill_n 的第一个迭代器参数是插入迭代器时则其可以改变对应容器的大小并插入指定元素

copy:

 #include <iostream>
#include <algorithm>
#include <list>
#include <deque>
#include <vector>
using namespace std; int main(void){
int a1[] = {, , , , , , , , , };
int a2[sizeof(a1) / sizeof(*a1)];//a2与a1的大小一样
auto ret = copy(begin(a1), end(a1), begin(a2));//将a1的内容拷贝到a2,返回目标迭代器递增之后的值
for(const auto indx : a2){
cout << indx << " ";
}
cout << endl;
cout << (ret == end(a2)) << endl;// list<int> l(, );
deque<int> f;
copy(l.begin(), l.end(), back_inserter(f));
for(const auto indx : f){
cout << indx << " ";
}
cout << endl;//1 1 1 1 1 vector<int> v;//空容器
v.reserve();//虽然该容器现在被分配了5个int空间,但其仍然是空容器
copy(l.begin(), l.end(), back_inserter(v));//向空容器拷入元素,改变了元素大小,必须使用插入迭代器
cout << v.size() << endl;//
cout << v.capacity() << endl;//
for(const auto indx : v){
cout << indx << " ";
}
cout << endl; vector<int> v1();//一个含有5个元素的容器
copy(l.begin(), l.end(), v1.begin());//只是替换原有元素,不需要用插入迭代器
for(const auto indx : v1){
cout << indx << " ";
}
cout << endl;//1 1 1 1 1
return ;
}

注意:越界问题

对于要改变容器大小的地方不能用普通迭代器

replace/replace_copy

 #include <iostream>
#include <algorithm>
#include <forward_list>
#include <vector>
using namespace std; int main(void){
forward_list<int> f(, );
replace(f.begin(), f.end(), , );//将f中所有0替换成1024
for(const auto indx : f){
cout << indx << " ";
}
cout << endl << endl; forward_list<int> l(, );
vector<int> v;
replace_copy(l.cbegin(), l.cend(), back_inserter(v), , );//将l拷贝到v并将v中元素值为0的修改成42
for(const auto indx : l){
cout << indx << " ";
}
cout << endl;
for(const auto indx : v){
cout << indx << " ";
}
cout << endl; return ;
}

注意:对于要改变容器大小的地方不能用普通迭代器,如:本例中 replace_copy 中因为 v 是个空迭代器,若以第三个参数必须用插入迭代器

重排容器元素的算法:

unique:

 #include <iostream>
#include <algorithm>
#include <vector>
using namespace std; void work(vector<string> &words){
sort(words.begin(), words.end());//unique只剔除相邻的相同元素
auto end_unique = unique(words.begin(), words.end());//将相邻的相同的元素"删除",返回一个指向不重复值范围末尾的迭代器
words.erase(end_unique, words.end());//上面的"删除"并不是真的删除,只是覆盖了而已,我们通过erase真正的将其删除
} int main(void){
vector<string> v = {"ac", "ab", "ac", "a", "a"};
work(v);
for(const auto indx : v){
cout << indx << " ";
}
cout << endl;//a ab ac return ;
}

注意:unique 只剔除相邻的相同元素

将相邻的相同的元素 "删除",返回一个指向不重复值范围末尾的迭代器。但其不真正的删除元素,只是将重复的值移到迭代器末尾而已,也可能会将其覆盖

谓词:

谓词是一个可调用的表达式,其返回结果是一个能用作条件的值。标准库算法所使用的谓词分两类:一元谓词(意味着它们只接受单一参数) 和二元谓词(意味着它们有两个参数)。接受谓词参数的算法对输入序列中的元素调用谓词。因此,元素类型必须能转换为谓词参数类型。如:sort 能接受一个二元谓词参数,这个谓词用来代替 < 来比较元素

sort 和 stable_sort:

sort 和 stable_sort 的使用规则完全一样,有区别的是带有 stable 的是稳定排序~

partition 和 stable_partition:

 #include <iostream>
#include <algorithm>
#include <vector>
using namespace std; bool is_longer_than_5(const string &s){
return s.size() >= ;
} int main(void){
vector<string> v1 = {"fjskf", "fjslfjksl", "fjsklfk", "f", "fdds", "fjs", "fjslf"};
vector<string> v2 = {"fjskf", "fjslfjksl", "fjsklfk", "f", "fdds", "fjs", "fjslf"}; auto pos1 = partition(v1.begin(), v1.end(), is_longer_than_5);//该算法是非稳定的
auto pos2 = stable_partition(v2.begin(), v2.end(), is_longer_than_5);//该算法是稳定的 for(auto it = v1.begin(); it != pos1; it++){
cout << *it << " ";
}
cout << endl; for(auto it = v2.begin(); it != pos2; it++){
cout << *it << " ";
}
cout << endl; return ;
}

泛型1(一些algorithm函数)的更多相关文章

  1. C#的泛型委托与闭包函数

    前些天Wendy问我说Func<T, ResultT>是个什么意思,初学C#都觉得这样的写法很奇葩,甚至觉得这样写有点诡异,其实以我来看,这是体现C#函数式编程的又一个亮点. 从MSDN上 ...

  2. Kotlin中的“忍者”函数 —— 理解泛型的能力(KAD 12)

    作者:Antonio Leiva 时间:Feb 8, 2017 原文链接:https://antonioleiva.com/generic-functions-kotlin/ Kotlin的一些特性组 ...

  3. c++中常用的泛型算法

    std中定义了很好几种顺序容器,它们自身也提供了一些操作,但是还有很多算法,容器本身没有提供. 而在algorithm头文件中,提供了许多算法,适用了大多数顺序容器.与c++11相比,很多函数在 c+ ...

  4. 窥探Swift之使用Web浏览器编译Swift代码以及Swift中的泛型

    有的小伙伴会问:博主,没有Mac怎么学Swift语言呢,我想学Swift,但前提得买个Mac.非也,非也.如果你想了解或者初步学习Swift语言的话,你可以登录这个网站:http://swiftstu ...

  5. 转载:《TypeScript 中文入门教程》 9、泛型

    版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性. 组件不 ...

  6. Swift—泛型(上)

    1.泛型 泛型是一种非常灵活的语法,允许程序在函数.枚举.结构体.类中定义类型形参,这种类型形参实际代表的类型是动态改变的——程序可以等到真正使用这些函数.枚举.结构体.类时才为这些类型形参传入实际的 ...

  7. C#的函数柯里化

    前面说到了C#的泛型委托和闭包函数,在函数是程序设计里还有一个重要特征是柯里化... 柯里化就是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结 ...

  8. 【C#进阶系列】12 泛型

    泛型是CLR和编程语言提供的一种特殊机制,它用于满足“算法重用”  . 可以想象一下一个只有操作的参数的数据类型不同的策略模式,完全可以用泛型来化为一个函数. 以下是它的优势: 类型安全 给泛型算法应 ...

  9. C++ find 函数用法

    头文件 #include <algorithm> 函数实现 template<class InputIterator, class T> InputIterator find ...

随机推荐

  1. delphi IOS发布添加其他资源文件

    添加自己的文件. Project>Deployment>Add File Remote Path android and IOS: assets\internal\ TPath.GetDo ...

  2. 你是真的了解ssh吗 说说你不知道的ssh

    Ssh命令——基石天赋 主要参数说明: -l 指定登入用户 -p 设置端口号 -f 后台运行,并推荐加上 -n 参数 -n 将标准输入重定向到 /dev/null,防止读取标准输入 -N 不执行远程命 ...

  3. 构造IOCTL命令的学习心得-----_IO,…

    在编写ioctl代码之前,需要选择对应不同命令的编号.为了防止对错误的设备使用正确的命令,命令号应该在系统范围内唯一,这种错误匹配并不是不会发生,程序可能发现自己正在试图对FIFO和audio等这类非 ...

  4. Linux下安装配置MySQL5.7服务器

    Linux下安装配置MySQL服务器 一.安装环境 ============ OS:centos6.8 MySQL:mysql-5.7.16-linux-glibc2.5-x86_64.tar.gz ...

  5. consul watch

    consul watch -type key -key mhc ./key_handler.py [root@mhc consul]# cat key_handler.py #!/usr/bin/py ...

  6. mac下怎样删除冗余的环境变量?echo $PATH

    记下$PATH变量中冗余路径所处顺序,例如: /Users/zhang/.rvm/gems/ruby-2.1.2/bin:/Users/zhang/.rvm/gems/ruby-2.1.2@globa ...

  7. quartz在web.xml的配置

    第一步:下载所需的Jar包 commons-beanutils.ja.commons-collections.jar.commons-logging.jar.commons-digester.jar. ...

  8. zookeeper全局数据一致性及其典型应用(发布订阅、命名服务、帮助其他集群选举)

    ZooKeeper全局数据一致性: 全局数据一致:集群中每个服务器保存一份相同的数据副本,client 无论连接到哪个服务器,展示的数据都是一致的,这是最重要的特征. 那么zookeeper集群是怎样 ...

  9. HashMap和HashSet的相同点和不同点

    Map集合,就是有一对属性值的集合,属性包含key,和value.关键字key是唯一不重复的.Map是一个有序的集合,所以查询起来速度很快.而HashSet就像是把HashMap中value去掉,说白 ...

  10. codeforces:Roads in the Kingdom分析和实现

    题目大意:国家有n个城市,还有n条道路,每条道路连通两个不同的城市,n条道路使得所有n个城市相互连通.现在国家经费不足,要关闭一条道路.国家的不便度定义为国家中任意两个不同的城市之间的距离的最大值,那 ...