C++ STL 常用算法

标准库定义了一组泛型算法:因为它们实现共同的操作,所以称之为“算法”;而“泛型”指的是它们可以操作在多种容器类型上,不但可作用于标准库类型,还可用在内置数组类型、甚至其他类型的序列上。大多数算法是通过遍历由两个迭代器标记的一段元素来实现其功能。使用泛型算法必须包含头文件 algorithm :

   #include

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

   #include

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

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

迭代器实参类型

通常泛型算法都是在标记容器(或其他序列)内的元素范围的迭代器上操作的。标记范围的两个实参类型必须精确匹配,它们必须指向同一个容器中的元素(或者超出容器末端的下一位置),并且如果两者不相等,则第一个迭代器通过不断地自增,必须可以到达第二个迭代器。对于带有两对迭代器参数的算法,如find_first_of:每对迭代器中,两个实参的类型必须精确匹配,但不要求两对之间的类型匹配。特别是,元素可存储在不同类型序列中,只要这两序列的元素可以比较即可。


一、只读算法

查找算法


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

搜索与统计算法


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

#include 
#include 
#include 
using namespace std;

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

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

    vector 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 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 << " ";
}



二、可变序列算法

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


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 版本。


三、排序算法


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 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::iterator iter= v.begin(); iter != v.end(); ++iter )  
    cout << *iter << " ";  
cout<::iterator iter = v.begin(); iter != v.end(); ++iter )
    cout << *iter << " ";
cout<


容器特有的算法

list 容器上的迭代器是双向的,而不是随机访问类型。因此,在此容器上不能使用需要随机访问迭代器的算法。这些算法包括 sort 及其相关的算法。还有一些其他的泛型算法,如 merge、remove、reverse 和 unique,虽然可以用在list 上,但却付出了性能上的代价。如果这些算法利用 list 容器实现的特点,则可以更高效地执行。

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


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

你可能感兴趣的:(C/C++)