写在前面: 为了能够使后续的代码具有高效简洁的特点,在这里讲一下STL,就不用自己写堆,写队列,但是做为ACMer不用学的很全面,我认为够用就好,我只写我用的比较多的。

什么是STL(STl内容):

容器(Container):
是一种数据结构,如list,vector,和deques ,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器;
迭代器(Iterator):
提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器也可以是那些定了operator*()以及其他类似于指针的操作符地方法的类对象;
算法(Algorithm):
是用来操作容器中的数据的模板函数。例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象,函数本身与他们操作的数据的结构和类型无关,因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用;
仿函数(Functor)
适配器(Adaptor)
分配器(allocator)

仿函数、适配器、与分配器用的比较少,甚至没用过!在这里不做说明,有兴趣可以自己学习一下,那个东西C++软件工程可能用的比较多。

一、算法 ( algorithm )

如果有不理解的容器知识可以先去看看容器

<一>查找算法(9个):判断容器中是否包含某个值

(可以去看看C++primer学学别的,但是我认为太多了没必要)
1.count:
利用等于操作符,把标志范围内的元素与输入值比较,返回相等元素个数。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{int a[14]={0,1,2,3,4,5,6,7,7,7,7,7,7,8};cout<<count(a,a+14,7)<<endl;vector<int> demo;for(int i=0;i<10;i++)demo.push_back(i);demo.push_back(1);cout<<count(demo.begin(),demo.end(),1)<<endl;
}
//运行结果 6 2;

2.count_if:
利用输入的操作符,对标志范围内的元素进行操作,返回结果为true的个数。

#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a)
{return (a>1);
}
int main()
{int a[14]={0,1,2,3,4,5,6,7,7,7,7,7,7,8};int po=count_if(a,a+14,cmp);cout<<po<<endl;vector<int> demo;for(int i=0;i<10;i++)demo.push_back(i);demo.push_back(1);int poi=count_if(demo.begin(),demo.end(),cmp);cout<<poi<<endl;
}// 运行结果   8 12
//看到网上大佬的代码写的比较深奥,特地去查了查书,我这样用没毛病的。

补充:捕获值列表,是允许我们在Lambda表达式的函数体中直接使用这些值,捕获值列表能捕获的值是所有在此作用域可以访问的值,包括这个作用域里面的临时变量,类的可访问成员,全局变量。捕获值的方式分两种,一种是按值捕获,一种是按引用捕获。顾名思义,按值捕获是不改变原有变量的值,按引用捕获是可以在Lambda表达式中改变原有变量的值。

[捕获值列表]:

1、空。没有使用任何函数对象参数。
2、=。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。
3、&。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。
4、this。函数体内可以使用Lambda所在类中的成员变量。
5、a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。
6、&a。将a按引用进行传递。
7、a, &b。将a按值进行传递,b按引用进行传递。
8、=,&a,&b。除a和b按引用进行传递外,其他参数都按值进行传递。
9、&, a, b。除a和b按值进行传递外,其他参数都按引用进行传递。

3.equal_range:
功能类似equal,返回一对iterator,第一个表示lower_bound,第二个表示upper_bound。

#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a)
{return (a>1);
}
int main()
{//   int a[14]= {0,1,2,3,4,5,6,7,7,7,7,7,7,8};//equal_range(a,a+14,auto po);vector<int> demo;for(int i=0; i<10; i++)  demo.push_back(i);demo.push_back(1);cout<<*equal_range(demo.begin(),demo.end(),7).first<<endl;cout<<*equal_range(demo.begin(),demo.end(),7).second<<endl;cout<<equal_range(demo.begin(),demo.end(),7).first-demo.begin()<<endl;cout<<equal_range(demo.begin(),demo.end(),7).second-equal_range(demo.begin(),demo.end(),7).first<<endl;
}
//也可以加cmp函数,同样适用于数组,在下文中不再举出数组的例子

4.find:
利用底层元素的等于操作符,对指定范围内的元素与输入值进行比较。当匹配时,结束搜索,返回该元素的一个InputIterator。

补充
InputIterator是用于输入的Iterator
OutputIterator是用于输出的Iterator
ForwardIterator是InputIterator,同时可以保证++运算不会使之失效
RandomIterator是ForwardIterator,同时具有+,-,+=,-=等运算及各种比较操作

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{int a[14]= {0,1,2,3,4,5,6,7,7,7,7,7,7,8};vector<int> demo;for(int i=0; i<14; i++)  demo.push_back(a[i]);demo.push_back(1);cout<<find(demo.begin(),demo.end(),8)-demo.begin()<<endl;
} //可以直接取地址获取值。

5.find_end:
在指定范围内查找"由输入的另外一对iterator标志的第二个序列"的最后一次出现。找到则返回最后一对的第一个ForwardIterator,否则返回输入的"另外一对"的第一个ForwardIterator。重载版本使用用户输入的操作符代替等于操作。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{int a[14]= {0,1,2,3,4,5,6,7,7,7,7,7,7,8};vector<int> demo;for(int i=0; i<14; i++)  demo.push_back(a[i]);demo.push_back(1);cout<<find_end(demo.begin(),demo.end(),a+2,a+3)-demo.begin()<<endl;
}

6.find_first_of:
在指定范围内查找"由输入的另外一对iterator标志的第二个序列"中任意一个元素的第一次出现。重载版本中使用了用户自定义操作符。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{int a[14]= {0,1,2,3,4,5,6,7,7,7,7,7,7,8};vector<int> demo;for(int i=0; i<14; i++)  demo.push_back(a[i]);demo.push_back(1);cout<<find_first_of(demo.begin(),demo.end(),a+2,a+3)-demo.begin()<<endl;
}

7.find_if:
使用输入的函数代替等于操作符执行find。返回的是迭代器,为了是大家更明白的理解,减去第一个元素的位置,就相当于得到了下标;

#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int w)   {return w>5;
}
int main()
{int a[14]= {0,1,2,3,4,5,6,7,7,7,7,7,7,8};vector<int> demo;for(int i=0; i<14; i++)  demo.push_back(a[i]);cout<< find_if(demo.begin(),demo.end(),cmp)-demo.begin();
}

8.lower_bound:
返回一个ForwardIterator,指向在有序序列范围内的可以插入指定值而不破坏容器顺序的第一个位置。重载函 数使用自定义比较操作。
在一个有序的范围内时间复杂度为log2n,普遍适用于二分算法。
跟3.equal_range的用法一样不过这个返回的是first
9.upper_bound:
返回一个ForwardIterator,指向在有序序列范围内插入value而不破坏容器顺序的最后一个位置,该位置标志 一个大于value的值。重载函数使用自定义比较操作。跟3.equal_range的用法一样不过这个返回的是second;

<二>排序和通用算法(7个):提供元素排序策略
  1. inplace_merge:

    合并两个有序序列,结果序列覆盖两端范围。重载版本使用输入的操作进行排序。

  2. merge:

    合并两个有序序列,存放到另一个序列。重载版本使用自定义的比较。 nth_element:
    将范围内的序列重新排序,使所有小于第n个元素的元素都出现在它前面,而大于它的都出现在后面。重载版本使用自定义的比较操作。

  3. partial_sort:

    对序列做部分排序,被排序元素个数正好可以被放到范围内。重载版本使用自定义的比较操作。

  4. partial_sort_copy:

    与partial_sort类似,不过将经过排序的序列复制到另一个容器。 partition:
    对指定范围内元素重新排序,使用输入的函数,把结果为true的元素放在结果为false的元素之前。 random_shuffle:
    对指定范围内的元素随机调整次序。重载版本输入一个随机数产生操作。 reverse:
    将指定范围内元素重新反序排序。 reverse_copy: 与reverse类似,不过将结果写入另一个容器。

  5. rotate:

将指定范围内元素移到容器末尾,由middle指向的元素成为容器第一个元素。

  1. rotate_copy:

    与rotate类似,不过将结果写入另一个容器。

  2. sort:(常用,相信大家都不陌生)

    以升序重新排列指定范围内的元素。重载版本使用自定义的比较操作。

     sort(首地址,第一个不合法地址(即末地址+1),cmp)//cmp可以缺省bool cmp()//可以用到结构体上 {return (); }
    
  3. stable_sort:

    与sort类似,不过保留相等元素之间的顺序关系。 stable_partition:
    与partition类似,不过不保证保留容器中的相对顺序。 <三>删除和替换算法(15个) copy:
    复制序列 copy_backward: 与copy相同,不过元素是以相反顺序被拷贝。 iter_swap:
    交换两个ForwardIterator的值。

<三>删除修改复制(12个):简单操作区间元素
  1. remove:

    删除指定范围内所有等于指定元素的元素。注意,该函数不是真正删除函数。内置函数不适合使用remove和 remove_if函数。

  2. remove_copy:
    将所有不匹配元素复制到一个制定容器,返回OutputIterator指向被拷贝的末元素的下一个位置。

  3. remove_if:

    删除指定范围内输入操作结果为true的所有元素。

  4. remove_copy_if:

    将所有不匹配元素拷贝到一个指定容器。

  5. replace:

    将指定范围内所有等于vold的元素都用vnew代替。

  6. replace_copy:

    与replace类似,不过将结果写入另一个容器。

  7. replace_if:

    将指定范围内所有操作结果为true的元素用新值代替。

  8. replace_copy_if:

    与replace_if,不过将结果写入另一个容器。

  9. swap:

    交换存储在两个对象中的值。

  10. swap_range:

    将指定范围内的元素与另一个序列元素值进行交换。

  11. unique: (常用于离散化)

    清除序列中重复元素,和remove类似,它也不能真正删除元素。重载版本使用自定义比较操作。

  12. unique_copy: (同上)

    与unique类似,不过把结果输出到另一个容器。

<四>排列组合算法(2个):提供计算给定集合按一定顺序的所有可能排列组合

以深搜的形式实现:

  1. next_permutation:

    取出当前范围内的排列,并重新排序为下一个排列。重载版本使用自定义的比较操作。

  2. prev_permutation:

    取出指定范围内的序列并将它重新排序为上一个序列。如果不存在上一个序列则返回false。重载版本使用 自定义的比较操作。

    //常以此方式使用,但时间复杂度N!这个。。。。
    do
    {//操作
    }while((next_permutation(首地址,第一个不合法地址)
    
<五>生成和异变算法(3个)
  1. fill:
    将输入值赋给标志范围内的所有元素。

    fill(首地址,第一个不合法地址,2); //该区间内全部赋值为2
    

    区别于memset,memset是按位赋值,只能赋每位值相同值。

    memset(首地址,value,(字节数)常用sizeof()获取)
    
  2. fill_n:

    将输入值赋给first到first+n范围内的所有元素。

    // 从开始以此赋值,3个5
    fill_n(首地址,3,5);
    
  3. transform:

    将输入的操作作用与指定范围内的每个元素,并产生一个新的序列。重载版本将操作作用在一对元素上,另外一个元素来自输入的另外一个序列。结果输出到指定容器。

    transform (原始对象首地址, 原始对象第一个不合法地址, 输出对象首地址, operate(操作函数));
    char operate(char c)//常用转化大小写,以此为例子
    {if (isupper(c)){return c+32;}return c;
    }
    
<六>关系算法(6个)
  1. equal:

    如果两个序列在标志范围内元素都相等,返回true。重载版本使用输入的操作符代替默认的等于操作符。

  2. includes:

    判断第一个指定范围内的所有元素是否都被第二个范围包含,使用底层元素的<操作符,成功返回true。重载版本使用用户输入的函数。

  3. max:(很多人问我,这不是cmath吗,呃。。。。。不是)
    返回两个元素中较大一个。重载版本使用自定义比较操作。

    max(3,5)的值是5;
    
  4. max_element:

    返回一个ForwardIterator,指出序列中最大的元素。重载版本使用自定义比较操作。

    max_element(a, a+6)  返回一个最大值位置指针
    
  5. min:

    返回两个元素中较小一个。重载版本使用自定义比较操作。

    min(3,5)的值是5;
    
  6. min_element:

    返回一个ForwardIterator,指出序列中最小的元素。重载版本使用自定义比较操作。

<七>集合算法(4个)
  1. set_union:
    构造一个有序序列,包含两个序列中所有的不重复元素。重载版本使用自定义的比较操作。

  2. set_intersection:
    构造一个有序序列,其中元素在两个序列中都存在。重载版本使用自定义的比较操作。

  3. set_difference:
    构造一个有序序列,该序列仅保留第一个序列中存在的而第二个中不存在的元素。重载版本使用自定义的比较操作。

  4. set_symmetric_difference:

构造一个有序序列,该序列取两个序列的对称差集(并集-交集)。
<八>堆算法(4个)
  1. make_heap:

    把指定范围内的元素生成一个堆。重载版本使用自定义比较操作。
    
  2. pop_heap:

    并不真正把最大元素从堆中弹出,而是重新排序堆。它把first和last-1交换,然后重新生成一个堆。可使用容器的back来访问被"弹出"的元素或者使用pop_back进行真正的删除。重载版本使用自定义的比较操作。

  3. push_heap:

    假设first到last-1是一个有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。在指向该函数前,必须先把元素插入容器后。重载版本使用指定的比较操作。

  4. sort_heap:

    对指定范围内的序列重新排序,它假设该序列是个有序堆。重载版本使用自定义比较操作。

疯子的算法总结(二) STL Ⅰ 算法 ( algorithm )相关推荐

  1. 程序设计与算法(二)算法基础-郭炜 1.3.1 称硬币

    程序设计与算法(二)算法基础-郭炜 1.3.1 称硬币 有12枚硬币.其中有11枚真币和1枚假币.假币和真币重量不同,但不知道假币比真币轻还是重.现在,用一架天平称了这些币三次,告诉你称的结果,请你找 ...

  2. 推荐算法(二)--算法总结

    转自:https://www.jianshu.com/p/1464eab67711 推荐算法分类 1 个性化推荐 1.1 基于用户推荐(Demographic-based Recommendation ...

  3. 北大郭炜教授《程序与算法(二)算法基础》学习笔记

    目录 第一章 枚举 例题一 完美立方 例题二 生理周期 例题三 称硬币 例题四 熄灯问题 第二章 递归(一) 例题一 求阶乘 例题二 汉诺塔 例题三 n皇后问题 例题四 逆波兰表达式 补充笔记(fro ...

  4. 程序设计与算法(二)--算法基础

    课程参考 mooc 北大郭炜老师 第一章 枚举 枚举:逐个的尝试答案 的一种问题求解策略 因为要一一举例,所以基本上都会用到循环(for ,while,switch,if 等等) 例题一:完美立方 形 ...

  5. 程序设计与算法(二)算法基础7.5分蛋糕

    问题描述: 有一块矩形大蛋糕,宽和高分别是整数w.h. 现要将其切成m块小蛋糕,每个小蛋糕都必须是矩形,且宽和高均为整数.切蛋糕时,每次切一块蛋糕,将其分成两个矩形蛋糕.请计算:最后得到的n块小蛋糕中 ...

  6. 程序设计与算法(二)算法基础1.4熄灯问题

    有一个由按钮组成的矩阵,其中每行有6个按钮,5行,共30个开关.每个按钮的位置上有一盏灯.当按下一个按钮后,该按钮以及周围位置(上边.下边.左边.右边)的灯都会改变一次.即,如果灯原来是点亮的,就会被 ...

  7. 程序设计与算法(二)算法基础8.4城堡问题

    题目描述: 下图是一个城堡的地形图请你编写一个程序,计算城堡一共有多少房间,最大的房间有多大.城堡 被分割成m*n(m≤50,n≤50)个方块,每个方块可以有0~4面墙. 输入 程序从标准输入设备读入 ...

  8. 头脑风暴优化算法(Brain Storming Optimization Algorithm, BSO)

    头脑风暴优化算法(Brain Storming Optimization Algorithm, BSO) 一.算法灵感 二.算法介绍 2. 1 初始化 2. 2 聚类 2. 3 个体更新 2. 4 算 ...

  9. 改进的白骨顶鸡优化算法(Improved Coot Optimization Algorithm,ICOOT)(原文作者)

    改进的白骨顶鸡优化算法(Improved Coot Optimization Algorithm,ICOOT)(原文作者) 一.算法灵感 二.算法介绍 2.1 初始化 2.2 跟随者位置更新(探索阶段 ...

  10. 【视频算法解析二】I3D

    [视频算法解析一] C3D算法 [视频算法解析二] I3D算法 [视频算法解析三] ECO算法 paper原文是"Quo Vadis, Action Recognition? A New M ...

最新文章

  1. 阿里云前端周刊 - 第 29 期
  2. php switch 函数,PHP丨PHP基础知识之条件语SWITCH判断「理论篇」
  3. UITableView的使用及代理方法
  4. NodeJS无所不能:细数10个令人惊讶的NodeJS开源项目
  5. 分析称2015年手机文娱将激增至540亿美元
  6. 5G 基站功耗,到底有多可怕?
  7. Python进阶(二)Python中的类继承、封装、多态使用方法
  8. linux-mint下搭建android,angularjs,rails,html5开发环境
  9. SQL Server2016的彻底删除
  10. wps下一步快捷键_WPS快捷键大全(最常用138个办公快捷键)
  11. matlab混沌指数的计算,Matlab编程之混沌系统李雅普诺夫指数分析
  12. 人脸识别门禁应用方案
  13. 路在脚下,却不知怎么去走?
  14. ESL第七章 模型评估及选择 【期望】测试误差、模型偏差估计偏差、【平均】乐观、AIC、参数有效数、BIC、最小描述长度、VC/结构风险最小化、一标准误差准则/广义交叉验证、【留一】自助/.632估计
  15. pentaho使用步骤简介
  16. Excel VBA合并不同工作簿所有工作表到一张工作表
  17. cannot import watershed from skimage.morphology
  18. 「自然语言处理(NLP)」【爱丁堡大学】基于实体模型的数据文本生成!!
  19. 渗透测试基础- - -web日志分析
  20. PHP 微信网页授权获取用户信息

热门文章

  1. oracle行迁移实验,Oracle 行迁移 amp; 行链接的检测与消除
  2. 物体运动到一个点停止_运用SolidWorks运动仿真来做的最速降线及其验证,来看看我的办法...
  3. python遥感影像分类代码_python,sklearn,svm,遥感数据分类,代码实例
  4. linux fpga通信,基于Linux的FPGA通信技术研究与实现
  5. win10下 Ubuntu 18.04 LTS 的安装及 rlt8821ce网卡驱动的安装
  6. Silverlight 5 beta新特性探索系列:9.视频快进快退和TextSearch对象对文字项查询
  7. Oracle正则表达式函数:regexp_like、regexp_substr、regexp_instr、regexp_replace
  8. 点击之后从浏览器回到微信界面的方法
  9. Java笔记-字符串编码与解码以及编码表原理
  10. 对Hibernate赖加载对象在session容器之外的获取方法