STL中常用算法总结


  STL算法众多,很难一一概括,对于我们日常软件开发而言,其实也不需要全部掌握,我们只需要掌握其中最常用的算法并能熟练使用即可。

查找算法

  • count:利用等于操作符,把标志范围内的元素与输入值比较,返回相等元素个数;
  • count_if:利用输入操作赋,对标志范围内的元素进行操作,返回结果为true的个数;
  • equal_range:功能类似equal,返回一对iterator,第一个表示lower_bound,第二个表示upper_bound;
  • find:利用底层元素的等于操作赋,对指定范围内的元素与输入值进行比较,当匹配时,结束搜索,并返回指向该元素的iterator;
  • find_if:使用输入的函数代替等于操作符执行find;

  相关实例代码如下:

#include <algorithm>
#include <vector>
#include <stdlib.h>
#include <iostream>

using namespace std;
int main(int argc, char *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 20; ++i)
    {
        int value = rand() % 10;
        cout << "value" << i << ":" << value << endl;
        vec.push_back(value);
    }

    //count
    cout << "count(== 5):" << count(vec.begin(), vec.end(), 5) << endl;

    //count_if
    cout << "count(< 5)" << count_if(vec.begin(), vec.end(), bind2nd(less<int>(), 5)) << endl;

    auto between = [](int value)->bool {
        if (value > 5 && value < 15)
            return true;
        else
            return false;
    };
    cout << "count(5 < ... < 15)" << count_if(vec.begin(),vec.end(),between) << endl;

    //equal_range
    typedef vector<int>::iterator iterator;
    pair<iterator,iterator> pairIter;
    cout << "pairIter.first:" << *(pairIter.first) << endl;
    cout << "pairIter.second:" << *(pairIter.second) << endl;

    //find
    cout << "find(5)" << *find(vec.begin(),vec.end(),5);

    //find_if
    cout << "find_if( > 5)" << *find_if(vec.begin(),vec.end(),bind2nd(greater<int>(),5));
     
    return 0;
}

  需要注意以下几点:

  • equal_range最好针对有序序列进行查找,否则很有可能找不到;
  • 类似于count_if()、find_if()这种函数,其第三个参数,我们可以使用普通函数,也可以使用lambda函数,也可以使用仿函数,当条件只是大于小于时,less<>()、greater<>()是最佳选择;

排序算法

  • reverse:将指定范围内的元素反序排序;
  • sort:以升序重新排列指定范围内的元素。重载版本使用自定义的比较操作。

  相关实例代码如下:

#include <algorithm>
#include <stdlib.h>
#include <vector>
#include <iostream>

using namespace std;
int main(int argc, char *argv[])
{
    vector<int> vec;
    for (int i = 0; i < 20; ++i)
    {
        int value = rand() % 10;
        cout << "value" << i << ":" << value << endl;
        vec.push_back(value);
    }

    //reverse
    reverse(vec.begin(),vec.end());

    //sort
    sort(vec.begin(),vec.end(),bind2nd(greater<int>(),5));

    return 0;
}

  需要注意以下几点:

  • STL中通用的排序算法只能适用于随机存取迭代器,因此list不能调用,但是list自定义了其sort排序算法;
  • 对于sort函数,自定义比较器时,如果return (first < second),那么意味着符合升序,对于不符合这种序列的元素,sort函数都将交换位置,return (first < second)则相反。参考:如何自定义sort函数中的比较函数

删除算法

  • remove:删除指定范围内所有等于指定元素的元素;
  • remove_If:删除指定范围内所有符合条件的元素;

  相关实例代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

int main()
{
    vector<int> vec;
    for (int i = 0; i < 10; ++i)
        vec.push_back(rand() % 5);

    //remove
    remove(vec.begin(),vec.end(),5);

    //remove_if
    remove_if(vec.begin(),vec.end(),bind2nd(greater<int>(),5));

    return 0;
}

  需要注意以下几点:

  • 两个算法都返回变动后的序列新的逻辑终点,也就是最后一个未被移除元素的下一位置,我们应当使用这个新的逻辑重点取代原始终点end(),但在移除过程后begin()仍然可用,因为算法会把原本置于后面的未移除元素向前移动,以覆盖被移除元素;
  • 由于会发生元素变动,所以这些算法不能用于关联式容器,但是关联式容器提供了成员函数erase();
  • list提供了一个等效成员函数remove():不是重新赋值元素,而是重新安排指针,因此具有更佳性能;

替换算法

  • replace:将指定范围内所有等于指定元素的元素使用新元素代替;
  • replace_if:将指定范围内所有符合条件的元素都用新元素代替;
  • swap:交换存储在两个对象中的值;

  相关实例代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

int main()
{
    vector<int> vec;
    for (int i = 0; i < 10; ++i)
        vec.push_back(rand() % 5);

    //replace
    replace(vec.begin(),vec.end(),5,10);

    //replace_if
    replace_if(vec.begin(),vec.end(),bind2nd(greater<int>(),5),10);

    //swap
    int a = 10;
    int b = 5;
    swap(a,b);

    return 0;
}

  需要注意以下几点:

  • swap()函数的最大优势在于,通过模板特化或者函数重载,我们可以为更复杂的性别提供特殊的实用版本,我们交换对象内部成员,不必反复赋值,这无疑将会大大节约时间,但需要注意,STL提供的swap只是一个浅拷贝,如果需要深拷贝,需要我们自己实现;但无论如何,swap()函数操作带来效率上的提升是毋庸置疑的,对于我们自定义的性别,我们应当尽量提供swap()特化版本;

for_each()算法

  for_each()算法非常灵活,它可以以不同的方式存取、处理、修改每一个元素;代码示例如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

void print_elem(int value)
{
    cout << value << endl;
}

int main()
{
    vector<int> vec;
    for (int i = 0; i < 10; ++i)
        vec.push_back(rand() % 5);

    for_each(vec.begin(),vec.end(),print_elem);    

    return 0;
}

  以上就是STL中最常用的几种算法,其他STL算法相对而言使用率较少,如果想要更加全面的了解STL算法,可以参考下面这篇博客:参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值