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

只读算法:

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. Python多线程-线程锁

    多线程修改一份数据时需要用到线程锁,以防止数据修改出错 #-*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" import threa ...

  2. PHP字符串的处理(四)-HTML标签的字符串格式化

    和html标签相关的字符串格式化 nl2br()  //在字符串中每个新行"\n"之前插入html换行符"<br />" <?php echo ...

  3. Android 4 学习(14):Internet Resources

    参考<Professional Android 4 Development> 使用Internet资源 打开URI String myFeed = getString(R.string.m ...

  4. day63-webservice 01.cxf介绍

    CXF功能就比较强了.CXF支持soap1.2.CXF和Spring整合的非常密切.它的配置文件基本就是Spring的配置文件了.CXF是要部署在服务器才能用的.CXF得放到Web容器里面去发布.CX ...

  5. 【HDU4301】Divide Chocolate

    题意 有一块n*2的巧克力,将它分成k块,问有多少种方法. 分析 emmm是dp没错了. 最容易想到的状态定义是f[i][j],意思是前i行,分成j块的方案数.但是发现没法转移.(后面会说一下为什么· ...

  6. mfs权威指南

    1. 我在性能测试中间遇到些问题,因为我时间有限,所以希望大家一起来测试解决,群策群力.有什么问题请大家及时指出来,因为我也处在一个不断摸索的阶段. 2. mfs不多做介绍,具体细节请参考本版mfs实 ...

  7. jmap, jhat命令

    jmap命令有下面几种常用的用法 jmap [pid] jmap -histo:live [pid] >a.log jmap -dump:live,format=b,file=xxx.xxx [ ...

  8. spring aop自动代理注解配置之一

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  9. Mybatis和Hibernate比较

    作者:乌拉拉链接:http://www.zhihu.com/question/21104468/answer/58579295来源:知乎著作权归作者所有,转载请联系作者获得授权. 1.开发对比开发速度 ...

  10. javascript总结13:循环语句

    1 While循环 While(条件表达式){ 只要条件表达式结果为true,循环一直执行,当条件表达式结果为false的时候,循环终止 } While循环语句需现在循环体外定义变量. 2 for循环 ...