STL标准库-算法-常用算法

摘要: 摘要: 摘要: 技术在于交流、沟通,本文为博主原创文章转载请注明出处并保持作品的完整性

介绍11种STL标准库的算法,从这11种算法中总结一下算法的基本使用

1.accumulate() 累加

2.for_each() for一段区间 做你指定的行为

3.replace(), replace_if(), replace_copy() 替换函数

4.count(), count_if() 计数

5.find() 查找

6.sort() 排序

7.binary_search()查看元素是否在指定区间



一 accumulate(),累加,将指定区域内的value累加起来

源码及参数介绍

//默认累加算法,将传进的__first(begin()迭代器)位置,至__last(end()迭代器),与init求和
template<typename _InputIterator, typename _Tp>
    inline _Tp
    accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
    {
      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
      __glibcxx_requires_valid_range(__first, __last);

      for (; __first != __last; ++__first)
    __init = __init + *__first;
      return __init;
    }

//自定义accumulate 按照指定的要求做”累加”操作
  template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
    inline _Tp
    accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
           _BinaryOperation __binary_op)
    {
      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
      __glibcxx_requires_valid_range(__first, __last);

      for (; __first != __last; ++__first)
    __init = __binary_op(__init, *__first);
      return __init;
    }

基本使用

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

namespace wzj000 {
    int myfunc(int x, int y) {return x+2*y;}

    struct myclass{
        int operator()(int x, int y){return x+3*y;}
    };

    void test_accumulate()
    {
        int init = 100;
        int num[]  {10, 20, 30};

        cout<<"default accumulate: " << accumulate(num, num+3, init)<< endl; //100 + 10 + 20 + 30 默认累加

        cout << "using minus: " << accumulate(num, num+3, init, minus<int>())<< endl; //100 - 10 - 20 - 30 将累加改为递减

        cout << "using custom function: " << accumulate(num, num+3, init, myfunc)<< endl; // 100 + 2*10 + 2*20 + 2*30 自定义"累加"规则 func

        cout << "suing custom object: " << accumulate(num, num+3, init, myclass())<< endl; // 100 + 3*10 + 3*20 + 3*30自定义"累加"规则 仿函数
    }
}

测试结果



二 for_each()  for一段区间 做你指定的行为

源码及参数介绍

template <class Inputerator, class Function>
Function for_each(Inputerator first, Inputerator last, Function f)
{//参数1 起始点 参数2 终点, 参数3 想要执行的操作
    for( ; first != last; ++first)
    {
        f(*first);
    }
    return f;
}

基本使用

namespace wzj001 {
    void myfunc(int i)
    {
        cout << " - " << i;
    }

    struct myclass{
        void operator()(int i)
        {
            cout << " ^ " << i;
        }
    };

    void test_for_each()
    {
        vector<int> myVector = {10, 20, 30};
        for_each(myVector.begin(), myVector.end(), myfunc);
        cout << endl;
    }

    void test_for_each_classFunc()
    {
        vector<int> myVector = {10, 20, 30};
        for_each(myVector.begin(), myVector.end(), myclass());
        cout << endl;
    }
}

测试结果



三 replace() 替换函数

replace_if()

   replace_copy()

源码及参数介绍

template <class ForwardIterator, class T>
void replace(Inputerator first, Inputerator last, const T & old_value, const T& new_value)
{//范围内所有等于old_value者都一new_value取代
    for( ; first != last; ++first)
    {
        if(*first == old_value)
            *first = new_value;
    }
}

template <class Inputerator, class Inputerator, class T>
void replace_if(ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value)
{//范围内所有满足pred()为true之元素都以new_value取代
    for( ; first != last; ++first)
    {
        if(pred(*first))
            *first = new_value;
    }
}

template <class Inputerator, class Outputerator, class T>
Outputerator replace_copy(ForwardIterator first, ForwardIterator last, Outputerator result, const T & old_value, const T& new_value)
{//范围内所有等于old_value者都以new_value放置新区域
//不符合者原值放入新区域
    for( ; first != last; ++first, ++result)
    {
        *result = *first == old_value ? new_value : *first;
    }
}

基本使用

namespace wzj002 {
    struct myclass{
        bool operator()(int i)
        {
            return i >=10 ? true : false;
        }
    };

    void test_replace()
    {
        vector<int> myVector = {10, 20, 30};
        replace(myVector.begin(), myVector.end(), 20 ,30);
        cout << "replace: ";
        for(auto i : myVector)
        {
            cout << i << " ";
        }
        cout << endl;
    }

    void test_replace_if()
    {
        vector<int> myVector = {10, 20, 30};
        replace_if(myVector.begin(), myVector.end(), myclass(), 30);
        cout << "replace_if: ";
        for(auto i : myVector)
        {
            cout << i << " ";
        }
        cout << endl;
    }

    void test_replace_copy()
    {
        vector<int> myVector = {10, 20, 30};
        vector<int> myNewVector;
        myNewVector.resize(3);
        replace_copy(myVector.begin(), myVector.end(), myNewVector.begin(), 20, 10);
        cout << "replace_if_New: ";
        for(auto i : myNewVector)
        {
            cout << i << " ";
        }
        cout << endl;

        cout << "replace_if_Old: ";
        for(auto i : myVector)
        {
            cout << i << " ";
        }
        cout << endl;
    }
}

测试结果



四 count() 计数

count_if()

源码及参数介绍

template <class Inputerator, class Outputerator, class T>
typename iterator_traits<Inputerator>::difference_type;
count(Inputerator first, Inputerator last, const T& value)
{
    typename iterator_traits<Inputerator>::difference_type;
    for( ; first != last; ++first)
        if(*first == value) //满足要求 值 == value 累计+1
            ++n;
    return n;
}

template <class Inputerator, class Outputerator, class Predicate>
typename iterator_traits<Inputerator>::difference_type;
count_if(Inputerator first, Inputerator last, Predicate pred)
{
    typename iterator_traits<Inputerator>::difference_type;
    for( ; first != last; ++first)
        if(pred(*first)) //满足指定要求 累计 +1
            ++n;
    return n;
}

count()和count_if()是全局算法,适用于array,vector,list,forward_list, deque

map,set,unordered_set/map由于是关联式容器,所有有自己的count()和count_if()函数

基本使用

namespace wzj003 {
    struct myclass{
        bool operator()(int i)
        {
            return i >= 20;
        }
    };

    void test_count()
    {
        vector<int> myVector = {10, 20, 30};
        cout << "count(): "<< count(myVector.begin(), myVector.end(), 20) <<endl;
    }

    void test_count_if()
    {
        vector<int> myVector = {10, 10, 20, 20, 30, 30};
        cout << "count_if(): " << count_if(myVector.begin(), myVector.end(), myclass())  <<endl;
    }
}

测试结果



五 find() 查找

  find_if()

find()和find_if()是全局算法,适用于array,vector,list,forward_list, deque

map,set,unordered_set/map由于是关联式容器,所有有自己的find()和find_if()函数

源码及参数介绍

template <class Inputerator, class T>
Inputerator find_if(Inputerator first, Inputerator last,  const T& value)
{
    while(first != last && *first != value)
        ++first;
    return first;
}

template <class Inputerator, class Predicate>
Inputerator find_if(Inputerator first, Inputerator last, Predicate pred)
{
    while(first != last && !pred(*first))
        ++first;
    return first;
}

基本使用

namespace wzj004 {
    struct myclass{
        bool operator()(int i)
        {
            return i >= 30;
        }
    };

    void test_find()
    {
        vector<int> myVector = {10, 20, 30};
        auto tmp = find(myVector.begin(), myVector.end(), 20);
        cout << "find(): "<< distance(myVector.begin(), tmp) <<endl;
    }

    void test_find_if()
    {
        vector<int> myVector = {10, 20, 30};
        auto tmp = find_if(myVector.begin(), myVector.end(), myclass());
        cout << "find_if(): " << distance(myVector.begin(), tmp)<<endl;
    }
}

测试结果



六 sort 排序

list和forward_list有成员sort()函数

set/map自动排序

array,vector,deque用全局sort()

namespace wzj005 {
    struct myclass{
        bool operator()(int i, int y)
        {
            return i > y;//  sort默认降序, 自定义为升序
        }
    };

    void test_sort()
    {
        vector<int> myVector = {10, 20, 30, 50, 70, 90, 100, 60, 80};
        sort(myVector.begin(), myVector.end());
        cout << "sort: ";
        for(auto i : myVector)
        {
            cout << i << " ";
        }
        cout << endl;

    }

    void test_sort_if()
    {
        vector<int> myVector = {10, 20, 30, 50, 70, 90, 100, 60, 80};
        sort(myVector.begin(), myVector.end(), myclass());
        cout << "sort_if: ";
        for(auto i : myVector)
        {
            cout << i << " ";
        }
        cout << endl;
    }
}

测试结果



七 binary_search()查看元素是否在指定区间内

源码及参数介绍

template <class Inputerator, class T>
bool binary_search(Inputerator first, Inputerator last, const T& val)
{//返回元素是否在指定区间
    first = std::lower_bound(first,last,val);
    return (first != last && !(val < *first));
}

基本使用

namespace wzj006 {
    struct myclass{
        bool operator()(int i, int y)
        {
            return i > y;
        }
    };

    void test_binary_search()
    {
        vector<int> myVector = {10, 20, 30, 50, 70, 90, 100, 60, 80};
        cout <<"binary_search: " << (binary_search(myVector.begin(), myVector.end(), 50) ? "true" : "false") << endl;
    }
}

测试结果

全部测试代码

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

namespace wzj000 {
    int myfunc(int x, int y) {return x+2*y;}

    struct myclass{
        int operator()(int x, int y){return x+3*y;}
    };

    void test_accumulate()
    {
        int init = 100;
        int num[]  {10, 20, 30};

        cout<<"default accumulate: " << accumulate(num, num+3, init)<< endl; //100 + 10 + 20 + 30 默认累加

        cout << "using minus: " << accumulate(num, num+3, init, minus<int>())<< endl; //100 - 10 - 20 - 30 将累加改为递减

        cout << "using custom function: " << accumulate(num, num+3, init, myfunc)<< endl; // 100 + 2*10 + 2*20 + 2*30 //自定义"累加"规则 func

        cout << "suing custom object: " << accumulate(num, num+3, init, myclass())<< endl; // 100 + 3*10 + 3*20 + 3*30//自定义"累加"规则 仿函数
    }
}

namespace wzj001 {
    void myfunc(int i)
    {
        cout << " - " << i;
    }

    struct myclass{
        void operator()(int i)
        {
            cout << " ^ " << i;
        }
    };

    void test_for_each()
    {
        vector<int> myVector = {10, 20, 30};
        for_each(myVector.begin(), myVector.end(), myfunc);
        cout << endl;
    }

    void test_for_each_classFunc()
    {
        vector<int> myVector = {10, 20, 30};
        for_each(myVector.begin(), myVector.end(), myclass());
        cout << endl;
    }
}

namespace wzj002 {
    struct myclass{
        bool operator()(int i)
        {
            return i >=10 ? true : false;
        }
    };

    void test_replace()
    {
        vector<int> myVector = {10, 20, 30};
        replace(myVector.begin(), myVector.end(), 20 ,30);
        cout << "replace: ";
        for(auto i : myVector)
        {
            cout << i << " ";
        }
        cout << endl;
    }

    void test_replace_if()
    {
        vector<int> myVector = {10, 20, 30};
        replace_if(myVector.begin(), myVector.end(), myclass(), 30);
        cout << "replace_if: ";
        for(auto i : myVector)
        {
            cout << i << " ";
        }
        cout << endl;
    }

    void test_replace_copy()
    {
        vector<int> myVector = {10, 20, 30};
        vector<int> myNewVector;
        myNewVector.resize(3);
        replace_copy(myVector.begin(), myVector.end(), myNewVector.begin(), 20, 10);
        cout << "replace_if_New: ";
        for(auto i : myNewVector)
        {
            cout << i << " ";
        }
        cout << endl;

        cout << "replace_if_Old: ";
        for(auto i : myVector)
        {
            cout << i << " ";
        }
        cout << endl;
    }
}

namespace wzj003 {
    struct myclass{
        bool operator()(int i)
        {
            return i >= 20;
        }
    };

    void test_count()
    {
        vector<int> myVector = {10, 20, 30};
        cout << "count(): "<< count(myVector.begin(), myVector.end(), 20) <<endl;
    }

    void test_count_if()
    {
        vector<int> myVector = {10, 10, 20, 20, 30, 30};
        cout << "count_if(): " << count_if(myVector.begin(), myVector.end(), myclass())  <<endl;
    }
}

namespace wzj004 {
    struct myclass{
        bool operator()(int i)
        {
            return i >= 30;
        }
    };

    void test_find()
    {
        vector<int> myVector = {10, 20, 30};
        auto tmp = find(myVector.begin(), myVector.end(), 20);
        cout << "find(): "<< distance(myVector.begin(), tmp) <<endl;
    }

    void test_find_if()
    {
        vector<int> myVector = {10, 20, 30};
        auto tmp = find_if(myVector.begin(), myVector.end(), myclass());
        cout << "find_if(): " << distance(myVector.begin(), tmp)<<endl;
    }
}

namespace wzj005 {
    struct myclass{
        bool operator()(int i, int y)
        {
            return i > y;//  sort默认降序, 自定义为升序
        }
    };

    void test_sort()
    {
        vector<int> myVector = {10, 20, 30, 50, 70, 90, 100, 60, 80};
        sort(myVector.begin(), myVector.end());
        cout << "sort: ";
        for(auto i : myVector)
        {
            cout << i << " ";
        }
        cout << endl;

    }

    void test_sort_if()
    {
        vector<int> myVector = {10, 20, 30, 50, 70, 90, 100, 60, 80};
        sort(myVector.begin(), myVector.end(), myclass());
        cout << "sort_if: ";
        for(auto i : myVector)
        {
            cout << i << " ";
        }
        cout << endl;
    }
}

namespace wzj006 {
    struct myclass{
        bool operator()(int i, int y)
        {
            return i > y;
        }
    };

    void test_binary_search()
    {
        vector<int> myVector = {10, 20, 30, 50, 70, 90, 100, 60, 80};
        cout <<"binary_search: " << (binary_search(myVector.begin(), myVector.end(), 50) ? "true" : "false") << endl;
    }
}

int main(int argc, char *argv[])
{
    wzj000::test_accumulate();
    wzj001::test_for_each();
    wzj001::test_for_each_classFunc();
    wzj002::test_replace();
    wzj002::test_replace_if();
    wzj002::test_replace_copy();
    wzj003::test_count();
    wzj003::test_count_if();
    wzj004::test_find();
    wzj004::test_find_if();
    wzj005::test_sort();
    wzj005::test_sort_if();
    wzj006::test_binary_search();
    return 0;
}

参考侯捷<<STL源码剖析>>

时间: 2024-12-12 02:50:17

STL标准库-算法-常用算法的相关文章

STL标准库-容器-set与multiset

摘要: 技术在于交流.沟通,转载请注明出处并保持作品的完整性. set与multiset关联容器 结构如下 set是一种关联容器,key即value,value即key.它是自动排序,排序特点依据key set的key不能相同.multiset的key相同.关联容器的查找效率要高于顺序容器很多很多. set和multiset不提供用来直接存取元素的任何操作函数,取值需要通过迭代器 一 定义 1.set/mulitiset以红黑树为底层结构,因此有元素自动排序的特性,排序是根据key,而set.m

参考C++STL标准库中对了的使用方法

http://www.cppblog.com/zhenglinbo/archive/2012/09/18/191170.html 参考:http://www.cppblog.com/zhenglinbo/archive/2012/09/18/191170.html 当然是使用c++中的STL 的queue啦.下面简要介绍一下使用方法. 1 准备工作 头文件 #include<queue> 2 声明和定义的方法.STL的队列是泛型模板,支持任何内置和构造类型. 比如对于刚才那个牛奶问题.我把状态

C++学习笔记之STL标准库(二)algorithm头文件即算法

#include <algorithm> algorithm头文件中主要包含的是一大堆模板函数,即STL库提供的算法,可以认为每个函数在很大程度上是独立的.提供的算法种类有: 1)adjacent_find //检测区间内第一对相等的相邻元素 template<class FwIt> FwIt adjacent_find(FwdIt first,FwdIt last);   //如果成功,返回first+N,N满足*(first+N) == *(first+N+1):如果不存在相等

STL标准库-容器-list

摘要: 技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性. list 表示非连续的内存区域,并通过一对指向首尾元素的指针双向链接起来,从而允许向前和向后两个方向进行遍历.在list 的任意位置插入和删除元素的效率都很高. 它的结构 一 定义 头文件 #include <vector> #include <iostream> #include <list> using namespace std; int main(int argc, const c

STL标准库-迭代器

摘要: 摘要: 技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性 本节主要介绍STL六大部件中的Iterators迭代器. 在语言方面讲,容器是一个class template, 算法是一个仿函数, 分配器class template, 迭代器是一个class template, 适配器class template, 分配器class template 从图中我们可以看出算法是看不到容器的,容器跟算法的交互必要用迭代器做桥梁,那么迭代器是怎样让容器和算法满足各自的需求的呢?

C++标准库之泛型算法

本文中算法都是指泛型算法. 基本要点: 1)算法使用迭代器进行操作. 2)不依赖容器,但容器希望使用算法,就必须提供接口. 3)通用算法永远不会执行容器操作.操作仅指:更改容器大小的操作.但,容器内部的算法不包括在通用中. 4)算法使用一个 可调用对象 来对元素进行操作.可 调用对象 通常为函数. 1,算法通常使用默认操作符 [<],[==],[>] 等. 2,本质上就是调用一个对象作为算法的比较. 3,通常的方式有:谓词,操作符重载,lambda表达式. 5)算法不检查写操作:即算法写入元素

STL标准库-容器-rb_tree

摘要: 摘要: 技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性 红黑树,关联式容器底层实现(map set),在使用中基本运用不到,但是还是想了解一下他的运作方式 Red_Black tree是平衡二分搜寻树(balanced binary search tree),它是高度平衡的二叉树,这样有利于search和insert. 红黑树提供遍历,如果如果按正常规则(++iter)遍历,便能获得排序状态 如上图,你会发现返回迭代器头的begin()函数指向的是"5"

STL标准库-仿函数

摘要: 摘要: 摘要: 技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性 仿函数的实现:声明一个类,重载它的operator call ("()"操作符) template<typename T> class lineFeed { public: void operator()(const T &x) { cout<<x<<endl; } }; 仿函数只为算法服务,但是像上面这种声明方式,虽然在有些时候可以使用,但是却不

STL标准库-容器-vector

摘要: 技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性. 我对向量容器vector的理解就是一个动态数组,内存连续,它是动态分配内存,且每次扩张的原来的二倍. 他的结构如下 一 定义 vector< 类型 > 标识符(最大容量,初始所有值) vector是一种类模板,那么他有很多行为与类相似 头文件 #include <vector> //a.定义 vector<typeName> v; vector<int> v; //b.拷贝构造