初探STL之算法

Posted gccbuaa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初探STL之算法相关的知识,希望对你有一定的参考价值。

算法

 

 

STL算法部分主要由头文件<algorithm>,<numeric>,<functional>组成。要使用 STL中的算法函数必须包括头文件<algorithm>,对于数值算法须包括<numeric>,<functional>中则定义了一些模板类,用来声明函数对象。


 

分类

 

STL中算法大致分为四类:
1、非可变序列算法:指不直接改动其所操作的容器内容的算法。
2、可变序列算法:指能够改动它们所操作的容器内容的算法。


3、排序算法:包含对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。


4、数值算法:对容器内容进行数值计算。

 

 

下面对全部算法进行仔细分类并标明功能:

 

 

算法介绍

 

查找算法


<一>查找算法(13个):推断容器中是否包括某个值


    adjacent_find: 在iterator对标识元素范围内。查找一对相邻反复元素。找到则返回指向这对元素的第一个元素的

ForwardIterator。

否则返回last。重载版本号使用输入的二元操作符取代相等的推断。
    

    binary_search: 在有序序列中查找value,找到返回true。

重载的版本号有用指定的比較函数对象或函数指针来推断

相等。


    count: 利用等于操作符。把标志范围内的元素与输入值比較,返回相等元素个数。


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


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

    find: 利用底层元素的等于操作符,对指定范围内的元素与输入值进行比較。

当匹配时,结束搜索,返回该元素的一个InputIterator。
    find_end: 在指定范围内查找"由输入的另外一对iterator标志的第二个序列"的最后一次出现。找到则返回最后一对的第一个ForwardIterator。否则返回输入的"另外一对"的第一个ForwardIterator。

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


    find_if: 使用输入的函数取代等于操作符运行find。


    lower_bound: 返回一个ForwardIterator。指向在有序序列范围内的能够插入指定值而不破坏容器顺序的第一个位置。

重载函数使用自己定义比較操作。
    upper_bound: 返回一个ForwardIterator。指向在有序序列范围内插入value而不破坏容器顺序的最后一个位置,该位置标志一个大于value的值。重载函数使用自己定义比較操作。


    search: 给出两个范围,返回一个ForwardIterator,查找成功指向第一个范围内第一次出现子序列(第二个范围)的位置,查找失败指向last1。

重载版本号使用自己定义的比較操作。


    search_n:在指定范围内查找val出现n次的子序列。重载版本号使用自己定义的比較操作。

 

 

 

排序和通用算法

 

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


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


    merge:合并两个有序序列,存放到还有一个序列。重载版本号使用自己定义的比較。


    nth_element:              将范围内的序列又一次排序。使全部小于第n个元素的元素都出如今它前面,而大于它的都出如今后面。

重载版本号使用自己定义的比較操作。


    partial_sort:对序列做部分排序,被排序元素个数正好能够被放到范围内。重载版本号使用自己定义的比較操作。
    partial_sort_copy: 与partial_sort类似。只是将经过排序的序列拷贝到还有一个容器。
    partition: 对指定范围内元素又一次排序,使用输入的函数,把结果为true的元素放在结果为false的元素之前。


    random_shuffle: 对指定范围内的元素随机调整次序。重载版本号输入一个随机数产生操作。


    reverse: 将指定范围内元素又一次反序排序。
    reverse_copy:  与reverse类似,只是将结果写入还有一个容器。


    rotate: 将指定范围内元素移到容器末尾,由middle指向的元素成为容器第一个元素。
    rotate_copy: 与rotate类似,只是将结果写入还有一个容器。


    sort: 以升序又一次排列指定范围内的元素。

重载版本号使用自己定义的比較操作。

    stable_sort:  与sort类似,只是保留相等元素之间的顺序关系。
    stable_partition: 与partition类似。只是不保证保留容器中的相对顺序。

 

 

删除和替换算法

 

<三>删除和替换算法(15个)
    copy:   复制序列
    copy_backward: 与copy同样。只是元素是以相反顺序被拷贝。


    iter_swap: 交换两个ForwardIterator的值。


    remove: 删除指定范围内全部等于指定元素的元素。注意,该函数不是真正删除函数。内置函数不适合使用remove和remove_if函数。
    remove_copy:将全部不匹配元素拷贝到一个制定容器。返回OutputIterator指向被拷贝的末元素的下一个位置。


    remove_if:  删除指定范围内输入操作结果为true的全部元素。


    remove_copy_if:  将全部不匹配元素复制到一个指定容器。


    replace:  将指定范围内全部等于vold的元素都用vnew取代。


    replace_copy:  与replace类似。只是将结果写入还有一个容器。


    replace_if: 将指定范围内全部操作结果为true的元素用新值取代。
    replace_copy_if: 与replace_if,只是将结果写入还有一个容器。


    swap:   交换存储在两个对象中的值。
    swap_range:   将指定范围内的元素与还有一个序列元素值进行交换。


    unique:  清除序列中反复元素,和remove类似,它也不能真正删除元素。

重载版本号使用自己定义比較操作。
    unique_copy:  与unique类似,只是把结果输出到还有一个容器。

 

 

排列组合算法

 

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


    next_permutation: 取出当前范围内的排列,并又一次排序为下一个排列。重载版本号使用自己定义的比較操作。
    prev_permutation:取出指定范围内的序列并将它又一次排序为上一个序列。

假设不存在上一个序列则返回false。

重载版本号使用自己定义的比較操作。

 

 

算术算法

 

 

<五>算术算法(4个)


    accumulate:  iterator对标识的序列段元素之和,加到一个由val指定的初始值上。

重载版本号不再做加法,而是传进来的二元操作符被应用到元素上。
    partial_sum:  创建一个新序列。当中每一个元素值代表指定范围内该位置前全部元素之和。重载版本号使用自己定义操作取代加法。
    inner_product:对两个序列做内积(相应元素相乘。再求和)并将内积加到一个输入的初始值上。重载版本号使用用户定义的操作。
    adjacent_difference:   创建一个新序列,新序列中每一个新值代表当前元素与上一个元素的差。重载版本号用指定二元操作计算相邻元素的差。

 

 

生成和异变算法

 

<六>生成和异变算法(6个)


    fill:    将输入值赋给标志范围内的全部元素。
    fill_n:    将输入值赋给first到first+n范围内的全部元素。
    for_each:  用指定函数依次对指定范围内全部元素进行迭代訪问。返回所指定的函数类型。该函数不得改动序列中的元素。


    generate:  连续调用输入的函数来填充指定的范围。
    generate_n:  generate函数类似。填充从指定iterator開始的n个元素。
    transform:   将输入的操作作用与指定范围内的每一个元素,并产生一个新的序列。

重载版本号将操作作用在一对元素上。另外一个元素来自输入的另外一个序列。

结果输出到指定容器。

 

 

 

关系算法

 

<七>关系算法(8个)


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

    includes:   推断第一个指定范围内的全部元素是否都被第二个范围包括。使用底层元素的<操作符,成功返回true。重载版本号使用用户输入的函数。


    lexicographical_compare:  比較两个序列。重载版本号使用用户自己定义比較操作。


    max: 返回两个元素中较大一个。

重载版本号使用自己定义比較操作。


    max_element: 返回一个ForwardIterator,指出序列中最大的元素。

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

重载版本号使用自己定义比較操作。


    min_element: 返回ForwardIterator,指出序列中最小的元素。重载版本号使用自己定义比較操作。


    mismatch:  并行比較两个序列。指出第一个不匹配的位置,返回一对iterator。标志第一个不匹配元素位置。

假设都匹配,返回每一个容器的last。重载版本号使用自己定义的比較操作。

 

 

集合算法

 

 

<八>集合算法(4个)


    set_union: 构造一个有序序列。包括两个序列中全部的不反复元素。重载版本号使用自己定义的比較操作。
    set_intersection: 构造一个有序序列,当中元素在两个序列中都存在。

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


    set_symmetric_difference: 构造一个有序序列,该序列取两个序列的对称差集(并集-交集)。


 

 

堆算法

 


<九>堆算法(4个)
    make_heap:  把指定范围内的元素生成一个堆。重载版本号使用自己定义比較操作。


    pop_heap:  并不真正把最大元素从堆中弹出,而是又一次排序堆。它把first和last-1交换,然后又一次生成一个堆。

可使用容器的back来訪问被"弹出"的元素或者使用pop_back进行真正的删除。重载版本号使用自己定义的比較操作。
    push_heap:  如果first到last-1是一个有效堆,要被增加到堆的元素存放在位置last-1,又一次生成堆。在指向该函数前,必须先把元素插入容器后。重载版本号使用指定的比較操作。
    sort_heap:   对指定范围内的序列又一次排序,它如果该序列是个有序堆。重载版本号使用自己定义比較操作。

 

 

 

 

举例:

 

find函数

 

#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;


int main( )
{
	vector<int> intv;
	for(int i=0;i<10;i++)
		intv.push_back(i);

	vector<int>::iterator inti;
	inti=find(intv.begin(),intv.end(),50);
	if(inti==intv.end())
		cout<<"没有找到匹配的值";
	else
		cout<<"找到了匹配的值";
	cout<<endl;

    inti=find(intv.begin(),intv.end(),5);
	if(inti==intv.end())
		cout<<"没有找到匹配的值";
	else
		cout<<"找到了匹配的值";


	return 0;
}

输出:

没有找到匹配的值

找到了匹配的值

 

 

find if 函数

 

#include "stdafx.h"
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
bool greater5(int i)
{
	return i>5;
}


int main( )
{
	vector<int> intv;
	for(int i=0;i<10;i++)
		intv.push_back(i);
	
	vector<int>::iterator inti;
	inti=find_if(intv.begin(),intv.end(),greater5);
	if(inti==intv.end())
		cout<<"没有比5大的值";
	else
		cout<<"第一个比5大的值是 :"<<*inti;   //输出6

   getchar();
   return 0;
}



copy函数

 

#include "stdafx.h"
#include <vector>
#include <list>
#include <algorithm>
#include <iostream>
using namespace std;

int main(int argc, _TCHAR* argv[])
{
	vector<int> intv;
	intv.push_back(2);
	intv.push_back(5);
	intv.push_back(3);

	list<int> intl;
	list<int>::iterator intliter;
	intl.push_back(6);
	intl.push_back(7);
	intl.push_back(8);
	intl.push_back(80);

	copy(intv.begin(),intv.end(),intl.begin());
	for(intliter=intl.begin();intliter!=intl.end();intliter++)
		cout<<*intliter<<"   ";

  getchar();
	return 0;
}

输出:

2  5  3  80

 

 

repalce函数

 

#include "stdafx.h"
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
	vector<int> intv;
	vector<int>::iterator intviter;
	intv.push_back(2);
	intv.push_back(5);
	intv.push_back(3);
	intv.push_back(50);
	intv.push_back(500);
    
	replace(intv.begin(),intv.end(),5,6);
	for(intviter=intv.begin();intviter!=intv.end();intviter++)
		cout<<*intviter<<"   ";

   getchar();
}

输出:

2  6  3  50  500

 

 

 


 

 

 

 

 

 

以上是关于初探STL之算法的主要内容,如果未能解决你的问题,请参考以下文章

比给定值最小的最大元素的 STL 算法

STL六大组件之算法

STL六大组件之算法

STL之迭代器(iterator)

STL之算法总结

STL初探——__default_alloc_template内存池