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

只读算法:

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. MVC原理图解

    注解: 视图中通过Action方法向控制器请求数据 控制器通过view()方法向视图呈现数据

  2. django-model之Q查询补充

    之前我们使用Q查询都是直接将Q对象写死到filter中,例如: 1.查询id大于1并且评论数大于100的书 print(models.Book.objects.filter(Q(nid__gt=1)& ...

  3. CSS秘密花园:多边框

    今天在查询CSS3动画相关资料时偶然发现这个,感觉有时还是挺方便的.原文链接:http://www.w3cplus.com/css3/css-secrets/multiple-borders.html ...

  4. saltstack系列(六)——zmq扩展(二)

    问题 我们已经熟练的掌握了REQ/REP模式,它是一个一对多的模式,一个REP对应多个REQ. 但是现实工作中,我们会遇到这样的难题,一个REP无法满足REQ的提问,因为REQ太多了,虽然可以增加一个 ...

  5. Markdown使用简单示例(每一个使用对应一个实际的markdown语法)

    1.标题示例:通过"#"数量表示几级标题.(一共只有1~6级标题,1级标题字体最大) 标题一 #标题一 标题二 #标题二 标题三 ###标题三 标题四 ####标题四 标题五 ## ...

  6. 在aspx页动态加载ascx页面内容,给GridView控件绑定数据

    在aspx页动态加载ascx页面内容 //加载ascx页面内容Control c1 = this.Page.LoadControl("WebUserControl1.ascx"); ...

  7. css-三边框,外边距和内边距

    <div style="width:100px;height:50px;border: solid black 1px;position: absolute;right: 500px; ...

  8. eclipse中代码里的黄色感叹号,怎么去掉?

    https://blog.csdn.net/Ideality_hunter/article/details/83007174

  9. ubuntu 安装两个版本的Anaconda

    1.下载anaconda2/anaconda3,下载地址:https://www.anaconda.com/download/#linux,anaconda官网如下所示,选择对应版本下载. 2.使用如 ...

  10. CF519E A and B and Lecture Rooms

    最近很颓……难题想不动……水题写不对,NOIP怕是