C++ STL 常用算法

标准库定义了一组泛型算法:因为它们实现共同的操作,所以称之为“算法”;而“泛型”指的是它们可以操作在多种容器类型上,不可作用于标准库

型,还可用在内置数组类型、甚至其他类型的序列上。大多数算法是通过遍历由两个迭代器标记的一段元素来实现其功能使用泛型算法必须包含头

件 algorithm :

       #include <algorithm>

标准库还定义了一组泛化的算术算法(generalized numeric algorithm),其命名习惯与泛型算法相同。使用这些算法则必须包numeric头文件:

       #include <numeric>

区别带一个函数参数的算法版本:大部分算法会提供比较或测试函数取代操符使用的版本,此版本在名字中加了 _if 后缀。

区别是否实现复制的算法版本很多算法将重新排列的元素写回其输入范围。标准库提供了复制版本,此版本的算法在名字中添加了 _copy 后缀。

迭代器实参类型

通常泛型算法都是在标记容器(或其他序列)内的元素范围的迭代器上操作的。标记范围的两个实参类型必须精确匹配它们必须指向同一个容器中的

元素(或者超出容器末端的下一位置),并且如果两者不相等,则第一个迭代器通过不断地自增,必须可以到达第二个迭代器。对于带有两对迭代器参

数的算法,如find_first_of:每对迭代器中,两个实参的类型必须精确匹配,但不要求两对之间的类型匹配特别是,元素可存储在不同类型序列中,

只要这两序列的元素可以比较即可。


一、只读算法

查找算法


find_if( beg, end, func ) :函数find 的带一个函数参数的 _if 版本,与 find 功能相同,条件:使函数 func 返回true。

搜索与统计算法

C++ STL 常用算法_第1张图片

count_if( beg, end, func ):函数count 的 _if 版本。 

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

bool evenNum( int n ) //是否为偶数
{ return n % 2; }

void main()
{
    int num = 6;
    vector<int> v1;
    for( int i = 0; i != 10; ++i )
        v1.push_back(i);
    vector<int>::iterator iter = find( v1.begin(), v1.end(), num ); //查找等于6的元素位置
    if( iter != v1.end() )
        cout << "匹配元素的索引: " << iter - v1.begin() << endl; //找到匹配元素位置6

    vector<int> v2;
    v2.push_back(6); 
    v2.push_back(5);
    v2.push_back(3);
    iter = find_first_of( v1.begin(), v1.end(), v2.begin(), v2.end() ); //第一个匹配元素是3
    if( iter != v1.end() )
        cout << "第一个匹配元素索引:" << iter - v1.begin() << endl; 

    int even_times = count_if( v1.begin(), v1.end(), evenNum ); //谓词函数参数,偶数个数为5个
    cout << "偶数个数 :" << even_times << endl; 
    
    vector<int> v3;
    v3.push_back(1);
    v3.push_back(1);
    v3.push_back(2);
    v3.push_back(2);
    //v3 非递减,每次循环 iter 跳向第一个大于当前元素的位置,因此只输出两个数 1,2
    for( iter = v3.begin(); iter != v3.end(); iter = lower_bound( iter, v3.end(), *iter ) )
        cout << *iter << " ";
}



二、可变序列算法

可变序列算法包括元素复制、变换、替换、填充、移除随机生成等。

C++ STL 常用算法_第2张图片

copy,transform,fill_n 和 generat 都需要保证:输出序列有足够的空间。 

remove函数并不真正删除元素,只是将要删除的元素移动到容器的末尾,删除元素需要容器 erase 函数来操作。同理,unique 函数也不会改变容器的

大小,只是这些元素的顺序改变了,是将无重复的元素复制到序列的前端,从而覆盖相邻的重复元素。unique 返回的迭代器指向超出无重复的元素范

围末端的下一位置。

remove_if( beg, end, func ):remove 的 _if 版本。

replace_if( beg, end, func, v2 ):replace 的 _if 版本。


_copy 版本,注意必须保证输出序列的大小不小于输入序列的大小。

remove_copy( beg, end, dest ):remove 的 _copy 版本,将反转后的序列输出到从dest 开始的区间。

remove_copy_if( beg, end, dest, func ):remove_copy 的 _if 版本。

replace_copy( beg, end, dest, v1, v2) :replace 的 _copy 版本。

replace_copy_if( beg, end, dest, func, v2 ):replace_copy 的 _if 版本。


三、排序算法

C++ STL 常用算法_第3张图片

partial_sort 对区间 [beg, end) 内的 mid - beg 个元素进行排序,将最小的 mid - beg 个元素有序放在序列的前 mid - beg 的位置上。

reverse_copy( beg, end, dest ):reverse 的 _copy 版本。

rotate_copy (beg, mid, end, dest):rotate 的 _copy 版本。


四、关系算法


标准库还提供 求最大值、最小值的 max 和 min 函数。

五、堆算法


vector<int> v;
v.push_back(3);
v.push_back(9);
v.push_back(17);
v.push_back(20);
v.push_back(12);

make_heap(v.begin(),v.end()); //用 vector 代替数组建立最大堆
cout << "堆: ";
for( vector<int>::iterator iter= v.begin(); iter != v.end(); ++iter )  
    cout << *iter << " ";  
cout<<endl;  

cout << "堆排序后: ";
sort_heap(v.begin(),v.end()); //堆排序
for( vector<int>::iterator iter = v.begin(); iter != v.end(); ++iter )
    cout << *iter << " ";
cout<<endl;


容器特有的算法

list 容器上的迭代器是双向的,而不是随机访问类型。因此,在此容器上不能使用需要随机访问迭代器的算法。这些算法包括 sort 及其相关的算法。还

有一些其他的泛型算法,如 merge、remove、reverse 和 unique,虽然可以用在list 上,但却付出了性能上的代价。如果这些算法利用 list 容器实现的

特点,则可以更高效地执行。

标准库为 list 容器定义了更精细的操作集合,使它不必只依赖于泛型操作。


lst.remove_if(func):remove() 的 _if 版本,删除使func 返回真的元素。

你可能感兴趣的:(C++,算法,泛型,STL)