本篇文章主要介绍泛型算法中的变易、排序、数值算法。

一、 变易算法

所谓变易算法是指那些改变容器中的对象的操作。

1.1 copy组

template
<class InputIterator,
class OutputIterator>

OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);

Copy操作是将两个输入迭代器之间的元素拷贝到输出迭代器处。注意拷贝时采用的是左对齐,会发生覆盖,使用时应该确保容器具有足够的大小,或者使用inserter迭代器。注意,由于采用的是左对齐的方式,可以实现向量元素的左移。

template
<class BidirectionalIterator1,
class BidirectionalIterator2>

BidirectionalIterator2 copy_backward (BidirectionalIterator1 first,

BidirectionalIterator1 last,

BidirectionalIterator2 result);

与普通的copy对应的,有一种右对齐的拷贝方式copy_backward,指定的输出迭代器为拷贝的末地址。

template
<class InputIterator,
class OutputIterator>

OutputIterator copy_n (InputIterator first, int num, OutputIterator result);

也可以采用起始迭代器和个数进行拷贝。

template
<class InputIterator,
class OutputIterator,
class UnaryPredicate>

OutputIterator copy_if (InputIterator first, InputIterator last,

OutputIterator result, UnaryPredicate pred);

也可以进行if条件的筛选,pred参数可以是函数指针,函数对象,也可以采用匿名函数。

 

1.2 swap组

template
<class T>
void swap (T& a, T& b);

Swap操作将a,b两个容器(不是迭代器)中的元素交换。

template
<class ForwardIterator1,
class ForwardIterator2>

ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1,

ForwardIterator2 first2);

也可以采用元素区间的方式进行交换。注意这里要求,第一个区间要小于第二个区间。函数的操作是将第一个区间的全部n个元素和第二个区间的前n个元素交换。也就是说,第二个区间后边的元素不会被改变。

1.3 transform

template
<class InputIterator,
class OutputIterator,
class UnaryOperation>

OutputIterator transform (InputIterator first1, InputIterator last1,

OutputIterator result, UnaryOperation op);

Transform会把容器中的元素进行相应的"转换",将每个元素丢给op函数进行操作,返回值存到result开始 位置中。如果result == first1,就是完整的转换操作。

template
<class InputIterator1,
class InputIterator2,

class OutputIterator,
class BinaryOperation>

OutputIterator transform (InputIterator1 first1, InputIterator1 last1,

InputIterator2 first2, OutputIterator result,

BinaryOperation binary_op);

这种重载的特点是,最后的操作不再是一个单参操作,而是双参操作。其第一个参数是first1到last1之间的每一个元素,而第二个参数则从first2开始,一一对应的进行选择。

1.4 replace组

template
<class ForwardIterator,
class T>

void replace (ForwardIterator first, ForwardIterator last,

const T& old_value,
const T& new_value);

普通的replace操作是,对于区间内的操作,如果等于old_value,则将其替换为新的值。

template
<class ForwardIterator,
class UnaryPredicate,
class T>

void replace_if (ForwardIterator first, ForwardIterator last,

UnaryPredicate pred,
const T& new_value );

也可以进行需要函数判断替换的replace_if操作,将区间内的每个元素扔给函数对象,如果返回值为真则进行替换。

template
<class InputIterator,
class OutputIterator,
class T>

OutputIterator replace_copy (InputIterator first, InputIterator last,

OutputIterator result,

const T& old_value,
const T& new_value);

Replace_copy操作是将区间内的元素先复制到目的迭代器指定的位置处,注意目的迭代器的容量问题。随后,并且对目的迭代器中的这些元素进行替换操作。

template
<class InputIterator,
class OutputIterator,
class T>

OutputIterator replace_copy_if (InputIterator first, InputIterator last,

OutputIterator result,

UnaryPredicate pred,
const T& new_value);

Replace_copy_if操作就是replace_if的带复制版本。

1.5 fill

template
<class ForwardIterator,
class T>

void fill (ForwardIterator first, ForwardIterator last,
const T& val);

将区间内的元素直接用这个值进行填充。

1.6 generate

template
<class ForwardIterator,
class Generator>

void generate (ForwardIterator first, ForwardIterator last, Generator gen);

将无参函数gen的返回值放在区间内。通常用于产生随机数,例如:

Generate(v.begin(),v.end(),rand);

1.7 remove组

template
<class ForwardIterator,
class T>

ForwardIterator remove (ForwardIterator first, ForwardIterator last,
const T& val);

Remove检查区间内的元素,如果相等,则将这个元素删除,最后返回一个迭代器,指向这个被删除后的区间中最后的元素。也就是说,如果原本最后一个元素没有被删除,则指向原本的最后一个元素;如果原本的最后一个元素也被删除了,则往前移动。

template
<class ForwardIterator,
class UnaryPredicate>

ForwardIterator remove_if (ForwardIterator first, ForwardIterator last,

UnaryPredicate pred);

在普通remove的基础上,通过检验判别函数(单参数 )决定是否remove。

template
<class InputIterator,
class OutputIterator,
class T>

OutputIterator remove_copy (InputIterator first, InputIterator last,

OutputIterator result,
const T& val);

在普通remove的基础上,改为先将其复制到新的位置,再对新的容器进行remove操作。

1.8 unique

template
<class ForwardIterator>

ForwardIterator unique (ForwardIterator first, ForwardIterator last);

    

template
<class ForwardIterator,
class BinaryPredicate>

ForwardIterator unique (ForwardIterator first, ForwardIterator last,

BinaryPredicate pred);

Unique操作,第一种形式是将相同的元素删除,只保留一份,返回的迭代器和remove操作一样;第二种是通过一个pred函数的返回值来查看是否是一样的,从中可以建立映射。

1.8 reverse

template
<class BidirectionalIterator>

void reverse (BidirectionalIterator first, BidirectionalIterator last);

Reverse函数将容器首位倒置,即"123"->"321";

1.9 rotate

template
<class ForwardIterator>

void rotate (ForwardIterator first, ForwardIterator middle,

ForwardIterator last);

Rotate即翻转操作,以middle为界,把middle前边的元素都移到最末尾,middle成为新的区间头。

1.9 random_shuffle

generator by default
(1)    

template
<class RandomAccessIterator>

void random_shuffle (RandomAccessIterator first, RandomAccessIterator last);

 

specific generator (2)    

template
<class RandomAccessIterator,
class RandomNumberGenerator>

void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,

RandomNumberGenerator& gen);

Shuffle即洗牌操作;将元素进行打乱。当进行自定操作时,则可能是N的阶乘中情况中的任何一种。当自定义操作时候,其行为是依次将第i号元素和第gen(i)号元素进行交换,一直到容器底。

1.10 partition

template
<class BidirectionalIterator,
class UnaryPredicate>

BidirectionalIterator partition (BidirectionalIterator first,

BidirectionalIterator last, UnaryPredicate pred);

Partition的行为是按照pred的返回值的true或false进行划分。划分后返回的迭代器result,使得[r.begin(),result )为true,[result,r.end())为false。

二、    排序算法

2.1    普通排序

2.1.1 sort

default
(1)    

template
<class RandomAccessIterator>

void sort (RandomAccessIterator first, RandomAccessIterator last);

custom (2)    

template
<class RandomAccessIterator,
class Compare>

void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

Sort有两种形式,第一重型是默认是调用了operator<函数进行比较,小者在前,也可以自行指定,两两相比返回值为1的元素在前。

2.1.2 partial_sort

default
(1)    

template
<class RandomAccessIterator>

void partial_sort (RandomAccessIterator first, RandomAccessIterator middle,

RandomAccessIterator last);

custom (2)    

template
<class RandomAccessIterator,
class Compare>

void partial_sort (RandomAccessIterator first, RandomAccessIterator middle,

RandomAccessIterator last, Compare comp);

进行部分排序,使得first到middle的元素是有序的,而middle到end的元素是打乱的(具体顺序不定)。这个排序可以用来找到前n大或者前n小的元素。例如,原来v中的元素为3,2,1,4,5,1,0;调用partial_sort(v.begin(),v.begin+4,v.end())后,结果是[0,1,1,2,…..(顺序不定)]

2.1.3 binary_search

default
(1)    

template
<class ForwardIterator,
class T>

bool binary_search (ForwardIterator first, ForwardIterator last,

const T& val);

custom (2)    

template
<class ForwardIterator,
class T,
class Compare>

bool binary_search (ForwardIterator first, ForwardIterator last,

const T& val, Compare comp);

在排好序的情况下,进行二分搜索,查找值为val的元素。元素必须先手动排序。

2.1.4 merge

default
(1)    

template
<class InputIterator1,
class InputIterator2,
class OutputIterator>

OutputIterator merge (InputIterator1 first1, InputIterator1 last1,

InputIterator2 first2, InputIterator2 last2,

OutputIterator result);

custom (2)    

template
<class InputIterator1,
class InputIterator2,

class OutputIterator,
class Compare>

OutputIterator merge (InputIterator1 first1, InputIterator1 last1,

InputIterator2 first2, InputIterator2 last2,

OutputIterator result, Compare comp);

将两个已经排好的序列进行快速有序合并。

2.2 集合排序算法

2.2.1 includes

template
<class InputIterator1,
class InputIterator2>

bool includes ( InputIterator1 first1, InputIterator1 last1,

InputIterator2 first2, InputIterator2 last2 );

 

template
<class InputIterator1,
class InputIterator2,
class Compare>

bool includes ( InputIterator1 first1, InputIterator1 last1,

InputIterator2 first2, InputIterator2 last2, Compare comp );

检查一个有序区间1内是否包含另一个有序区间2内的元素,注意如果排序方法不是operator <,则必须要显式的声明出来。所谓的包含是指,12345中包含了125,1234321包含了33,并不要求连续。

2.2 堆排序算法

2.2.1 make_heap

default
(1)    

template
<class RandomAccessIterator>

void make_heap (RandomAccessIterator first, RandomAccessIterator last);

custom (2)    

template
<class RandomAccessIterator,
class Compare>

void make_heap (RandomAccessIterator first, RandomAccessIterator last,

Compare comp );

生成一个堆,默认情况下采取operator<进行比较,生成一个大顶堆;如果进行大于比较,则是生成小顶堆。

这种堆在存储时采用从上到下,从左至右的方式进行存储。

2.2.2 push_heap

default
(1)    

template
<class RandomAccessIterator>

void push_heap (RandomAccessIterator first, RandomAccessIterator last);

custom (2)    

template
<class RandomAccessIterator,
class Compare>

void push_heap (RandomAccessIterator first, RandomAccessIterator last,

Compare comp);

Push_heap操作向堆中添加元素,并对其进行调整。其调整方法为先将其放到整个堆的末尾,然后再向前进行逐次交换。由于前面的元素都满足平衡二叉树的条件,这种方法的正确性得以保证。

2.2.3 pop_heap

default
(1)    

template
<class RandomAccessIterator>

void pop_heap (RandomAccessIterator first, RandomAccessIterator last);

custom (2)    

template
<class RandomAccessIterator,
class Compare>

void pop_heap (RandomAccessIterator first, RandomAccessIterator last,

Compare comp);

从堆顶弹出一个元素。对于大顶堆,则代表弹出最大元素。弹出后重新调整为平衡二叉树的方法是,先将其和整个堆末尾的元素进行一次交换,然后将其删除。随后,让新的根顶元素逐次向下比较交换,每次都与子节点中比自己大的较大者交换,知道这一节点大于其子节点或是不存在子节点。采用这种交换的方式,保证了平衡二叉树的紧密,而且具有logn的时间复杂度。

2.2.4 sort_heap

default
(1)    

template
<class RandomAccessIterator>

void sort_heap (RandomAccessIterator first, RandomAccessIterator last);

custom (2)    

template
<class RandomAccessIterator,
class Compare>

void sort_heap (RandomAccessIterator first, RandomAccessIterator last,

Compare comp);

利用出堆操作对堆进行排序。

三、 泛型数值算法

1.1 accumulate

sum (1)    

template
<class InputIterator,
class T>

T accumulate (InputIterator first, InputIterator last, T init);

custom (2)    

template
<class InputIterator,
class T,
class BinaryOperation>

T accumulate (InputIterator first, InputIterator last, T init,

BinaryOperation binary_op);

Accumulate操作是以init为初始值,和每个成员进行操作。默认情况下的操作为+=,也就是累加运算。如果指定了一个操作函数,那么每次操作result = op(*it,result);注意第一参数为容器元素。

例如,求1+…+100可以采用以下代码:

vector<int> v(100);

方式填满整个区间。

int sum = accumulate(v.begin(),v.end(),0);

 

1.2 inner_product

sum/multiply (1)    

template
<class InputIterator1,
class InputIterator2,
class T>

T inner_product (InputIterator1 first1, InputIterator1 last1,

InputIterator2 first2, T init);

custom (2)    

template
<class InputIterator1,
class InputIterator2,
class T,

class BinaryOperation1,
class BinaryOperation2>

T inner_product (InputIterator1 first1, InputIterator1 last1,

InputIterator2 first2, T init,

BinaryOperation1 binary_op1,

BinaryOperation2 binary_op2);

Inner_product是向量内积操作,例如,给定向量a[2] = {1,2};b[2] = {3,4};则默认情况下,返回值为1*3+2*4;自定义的方式下,则op2表示按位置一一对应时进行何种运算,而op1则表示对这些所有结果进行何种运算。例如,若使用inner_product(a,a+3,b,1,multiplies<int>(),plus<int>());则计算1*(1+3)*(2+4)的结果。

1.3 partial_sum

sum (1)    

template
<class InputIterator,
class OutputIterator>

OutputIterator partial_sum (InputIterator first, InputIterator last,

OutputIterator result);

custom (2)    

template
<class InputIterator,
class OutputIterator,
class BinaryOperation>

OutputIterator partial_sum (InputIterator first, InputIterator last,

 

一种zigzag形式的运算,如图所示,对1,2,3,4,5进行此种运算的过程是:

可以看到,产生的结果是一组数据,每一个数据都是前n个数据的累计。

1.4 adjacent_difference

difference (1)    

template
<class InputIterator,
class OutputIterator>

OutputIterator adjacent_difference (InputIterator first, InputIterator last,

OutputIterator result);

custom (2)    

template
<class InputIterator,
class OutputIterator,
class BinaryOperation>

OutputIterator adjacent_difference ( InputIterator first, InputIterator last,

OutputIterator result, BinaryOperation binary_op );

这个函数对相邻两个元素进行运算,第一个元素不动。默认情况下采取减操作,如图:

注意自行指定函数时,第一运算数为后边的元素。

[GeekBand] STL与泛型编程(3)的更多相关文章

  1. [GeekBand] STL与泛型编程(1)

    在C++语法的学习过程中,我们已经对模板有了基本的了解.泛型编程就是以模板为工具的.泛化的编程思想.本篇文章介绍了一些在之前的文章中没有涉及到的一些模板知识.泛型编程知识和几种容器.关于模板的一些重复 ...

  2. [GeekBand] STL与泛型编程(2)

    本篇文章在上一篇文章的基础上进一步介绍一些常用的容器以及STL的一些深入知识. 一. Stack和Queue 栈和队列是非常常用的两种数据结构,由deque适配而来.关于数据结构的知识这里就不在介绍了 ...

  3. STL与泛型编程-第一周笔记-Geekband

    1, 模板观念与函数模板 简单模板: template< typename T > T Function( T a, T b) {- } 类模板: template struct Obje ...

  4. [GeekBand] STL 仿函数入门详解

    本文参考文献::GeekBand课堂内容,授课老师:张文杰 :C++ Primer 11 中文版(第五版) page 37 :网络资料: 叶卡同学的部落格  http://www.leavesite. ...

  5. [GeekBand] STL vector 查找拷贝操作效率分析

    本文参考文献::GeekBand课堂内容,授课老师:张文杰 :C++ Primer 11 中文版(第五版) :网络资料: 叶卡同学的部落格  http://www.leavesite.com/ htt ...

  6. [GeekBand] STL Traits 使用简介

    本文参考文献::GeekBand课堂内容,授课老师:张文杰 :C++ Templates  15章节 :网络资料: http://blog.csdn.net/my_business/article/d ...

  7. STL与泛型编程(第一周)

    part 1 C++模版简介 一,模版概观 1.模板 (Templates)是C++的一种特性,允许函数或类(对象)通过泛型(generic types)的形式表现或运行. 模板可以使得函数或类在对应 ...

  8. STL与泛型编程-练习2-GeekBand

    练习题目: struct Programmer{ Programmer(const int id, const std::wstring name): Id(id), Name(name){ } vo ...

  9. STL与泛型编程-学习2-GeekBand

    9, 容器 Deque 双向队列 和vector类似, 新增加: push_front 在头部插入一个元素 pop_front 在头部弹出一个元素 Deque和vector内存管理不同: 大块分配内存 ...

随机推荐

  1. Java 中队列的使用

    刚才看见群里的一个朋友在问队列的使用,确实在现实的写代码中非常少使用队列的,反正我是从来没使用过.仅仅是学数据结构的时候学过. 以下是我写的一个小样例,希望有不足之处请提出改正.O(∩_∩)O~ 看代 ...

  2. Node.js 的Web server--Fenix

    Fenix 是提供给开发者使用的简单的一个 Web server, 是基于 Node.js 开发. 能够同一时候在上面执行非常多的项目. 最适合前端开发者使用. 能够通过免费的 Node.js 控制台 ...

  3. 一起聊聊 Swift 3.0

    Swift3.0将会给我们带来哪些改变: 1. 稳定二进制接口(ABI) ABI是什么呢?API大家都知道是应用程序接口 API只是提供函数签名 而ABI是系统和语言层面的 如果ABI稳定 意味着以后 ...

  4. S_ISREG等几个常见的宏 struct stat

    S_ISLNK(st_mode):是否是一个连接.S_ISREG(st_mode):是否是一个常规文件.S_ISDIR(st_mode):是否是一个目录S_ISCHR(st_mode):是否是一个字符 ...

  5. DebugView图文教程

    Debug信息捕获软件. 可以很方便的捕获系统实时输出的Debug信息,并保存为日志文件.可以远程捕获服务器上的Debug信息. 比较方便开发人员在系统发布前监控一些系统流程和异常,甚至在系统不大的情 ...

  6. 小白日记37:kali渗透测试之Web渗透-手动漏洞挖掘(三)-目录遍历、文件包含

    手动漏洞挖掘 漏洞类型 #Directory traversal 目录遍历[本台机器操作系统上文件进行读取] 使用者可以通过浏览器/URL地址或者参数变量内容,可以读取web根目录[默认为:/var/ ...

  7. 你真的会用UITableView嘛

    UITableView是工程开发中最经常使用到的UI控件,但是你真的了解它嘛,这里记录几点有用的但你可能并不知道的. 当我们的数据未能显示满一屏幕的时候,UITableView会显示多余的横线,这个时 ...

  8. cocos2d-x lua 触摸事件

    cocos2d-x lua 触摸事件 version: cocos2d-x 3.6 1.监听 function GameLayer:onEnter() local eventDispatcher = ...

  9. Ubuntu14.04 Kylin下 GO语言环境搭建

    sudo apt-get install golang gccgo安装 gcc -v 查看 --enable-languages=c,c++,objc,obj-c++,java,fortran,ada ...

  10. 安装Laravel之坎坷记述

    写这篇文章记录以及分享我安装Laravel框架的一些经验 过程如下: 1.按照官方的描述,第一步是先安装composer来管理依赖=>composer下载传送门 下载之后点击安装,按照提示它需要 ...