STL (13) 非变动型算法

Posted zzdoit

tags:

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

STL (13) 非变动型算法

    • algorithm是“算法”必须的头文件。
      • Non-modifying sequence operations (非变动式算法):算法过后,容器内部数据不发生改变。
        all_of
        Test condition on all elements in range (function template )
        any_of
        Test if any element in range fulfills condition (function template )
        none_of
        Test if no elements fulfill condition (function template )
        for_each
        Apply function to range (function template )
        find
        Find value in range (function template )
        find_if
        Find element in range (function template )
        find_if_not
        Find element in range (negative condition) (function template )
        find_end
        Find last subsequence in range (function template )
        find_first_of
        Find element from set in range (function template )
        adjacent_find
        Find equal adjacent elements in range (function template )
        count
        Count appearances of value in range (function template )
        count_if
        Return number of elements in range satisfying condition (function template )
        mismatch
        Return first position where two ranges differ (function template )
        equal
        Test whether the elements in two ranges are equal (function template )
        is_permutation
        Test whether range is permutation of another (function template )
        search
        Search range for subsequence (function template )
        search_n
        Search range for elements (function template )
    • all_of  Test condition on all elements in range (function template )
      测试范围内所有元素的条件(函数模板)???
      • 观察本质
        • cplusplus页面上的范例
          template<class InputIterator, class UnaryPredicate>
          bool all_of (InputIterator first, InputIterator last, UnaryPredicate pred)
          {
          while (first!=last) {
          if (!pred(*first)) return false;
          ++first;
          }
          return true;
          }

          ---------------------------------------------------------
          // all_of example
          #include <iostream> // std::cout
          #include <algorithm> // std::all_of
          #include <array> // std::array

          int main () {
          std::array<int,8> foo = {3,5,7,11,13,17,19,23};

          if ( std::all_of(foo.begin(), foo.end(), [](int i){return i%2;}) )
          std::cout << "All the elements are odd numbers.\n";

          return 0;
          }???
          ------------------------------------------------------
          Output:
          All the elements are odd numbers.?

          解释:
          1. [](int i){return i%2;})??? 这里表示一个匿名函数,C++11专属
          2. 些算法效率比较高:因为不是全部判断,只要其中有一个不符合,就返回false了。?



          ??
        • vs2015中代码如下:
          // TEMPLATE FUNCTION all_of
          template<class _InIt,class _Pr> inline
          bool _All_of_unchecked(_InIt _First, _InIt _Last, _Pr& _Pred)
          { // test if all elements satisfy _Pred
          for (; _First != _Last; ++_First)
          if (!_Pred(*_First))
          return (false);
          return (true);
          }????
      • all_of使用场景是很多的,它能帮我们判断容器内数据,是否符合我们的要求。
    • any_of  Test if any element in range fulfills condition (function template )
      • 观察本质
        • 与all_of成对出现,all_of是判断是否全部符合,any_of则是判断是否有一个符合。
        • 示例:
          template<class InputIterator, class UnaryPredicate>
          bool any_of (InputIterator first, InputIterator last, UnaryPredicate pred)
          {
          while (first!=last) {
          if (pred(*first)) return true;
          ++first;
          }
          return false;
          }
          ----------------------------------------------------------
          ??// any_of example
          #include <iostream> // std::cout
          #include <algorithm> // std::any_of
          #include <array> // std::array

          int main () {
          std::array<int,7> foo = {0,1,-1,3,-3,5,-5};

          if ( std::any_of(foo.begin(), foo.end(), [](int i){return i<0;}) )
          std::cout << "There are negative elements in the range.\n";

          return 0;
          }

          --------------------------------------------------------------------
          Output:
          There are negative elements in the range.


          解释:测试如果有一个元素满足条件
          ????
          ????
    • none_of  Test if no elements fulfill condition (function template ) 如果没有元素满足条件
      • 观察本质
        • 示例
          template<class InputIterator, class UnaryPredicate>
          bool none_of (InputIterator first, InputIterator last, UnaryPredicate pred)
          {
          while (first!=last) {
          if (pred(*first)) return false;
          ++first;
          }
          return true;
          }
          ---------------------------------------------------------
          ??
          // none_of example
          #include <iostream> // std::cout
          #include <algorithm> // std::none_of
          #include <array> // std::array

          int main () {
          std::array<int,8> foo = {1,2,4,8,16,32,64,128};

          if ( std::none_of(foo.begin(), foo.end(), [](int i){return i<0;}) )
          std::cout << "There are no negative elements in the range.\n";

          return 0;
          }

          -------------------------------------------------------------

          Output:
          There are no negative elements in the range.?????

          解释:测试如果没有元素满足条件
          ?

          ????
    • for_each Apply function to range (function template ) 将函数应用到范围
      • 观察本质
        template<class InputIterator, class Function>
        Function for_each(InputIterator first, InputIterator last, Function fn)
        {
        while (first!=last) {
        fn (*first);
        ++first;
        }
        return fn; // or, since C++11: return move(fn);
        }
        -------------------------------------------

        ??// for_each example
        #include <iostream> // std::cout
        #include <algorithm> // std::for_each
        #include <vector> // std::vector

        void myfunction (int i) { // function:
        std::cout << ‘ ‘ << i;
        }

        struct myclass { // function object type:
        void operator() (int i) {std::cout << ‘ ‘ << i;}
        } myobject;

        int main () {
        std::vector<int> myvector;
        myvector.push_back(10);
        myvector.push_back(20);
        myvector.push_back(30);

        std::cout << "myvector contains:";
        for_each (myvector.begin(), myvector.end(), myfunction);
        std::cout << ‘\n‘;

        // or:
        std::cout << "myvector contains:";
        for_each (myvector.begin(), myvector.end(), myobject);
        std::cout << ‘\n‘;

        return 0;
        }

        ----------------------------------------------------------------------

        Output:
        myvector contains: 10 20 30
        myvector contains: 10 20 30????

        解释:??要注意C++98 与C++11返回值的不同。
        C++11:Returns fn, as if calling std::move(fn).
        C++98:Returns fn.???
        ???
    • find Find value in range (function template ) 在范围内查找值
      • 观察本质:找到了,直接返回找到的值,没找到,返回last。(有效空间的后面位置)
        template<class InputIterator, class T>
        InputIterator find (InputIterator first, InputIterator last, const T& val)
        {
        while (first!=last) {
        if (*first==val) return first;
        ++first;
        }
        return last; //返回有效区间+1的位置
        }
        -------------------------------------------------------------------------------

        // find example
        #include <iostream> // std::cout
        #include <algorithm> // std::find
        #include <vector> // std::vector

        int main () {
        // using std::find with array and pointer:
        int myints[] = { 10, 20, 30, 40 };
        int * p;

        p = std::find (myints, myints+4, 30);
        if (p != myints+4)
        std::cout << "Element found in myints: " << *p << ‘\n‘;
        else
        std::cout << "Element not found in myints\n";

        // using std::find with vector and iterator:
        std::vector<int> myvector (myints,myints+4); //这里要注意,myints+4是有效区间+1的位置。
        std::vector<int>::iterator it;

        it = find (myvector.begin(), myvector.end(), 30);
        if (it != myvector.end())
        std::cout << "Element found in myvector: " << *it << ‘\n‘;
        else
        std::cout << "Element not found in myvector\n";

        return 0;
        }

        ---------------------------------------------------------------------------------

        ???????Output:
        Element found in myints: 30
        Element found in myvector: 30


        解释:???查找值需要“operator==”支持
        if (*first==val) return first; 核心代码:如果*first与val是相等的,返回first.?

        ------------------------vs2015代码----------------------------------
        template<class _InIt,
        class _Ty> inline
        _InIt _Find_unchecked1(_InIt _First, _InIt _Last, const _Ty& _Val, false_type)
        { // find first matching _Val
        for (; _First != _Last; ++_First)
        if (*_First == _Val)
        break;
        return (_First);
        }
        ????
      • 注意点:
        • 1 查找值需要“operator==”支持
        • 2 查找值需要遍历容器数据,迭代器需要支持"operator++"
        • 3 注意返回的位置,特别要注意数组和容器数据的不同,最后返回的位置last,在数组中是有效数据;而在前闭后开的容器中,last的位置是“有效数据+1”的无效数据。
        • 示例
          #include <iostream>
          #include "Algorithm.h"
          #include <array>
          class Demo
          {
          int no_;
          public:
          bool operator==(int num)
          {
          return no_ == num;
          }
          };
          int main ()
          ?{
          Demo demoArray[10];
          std::find(&demoArray[0], &demoArray[9], 20); //这里demoArray[9]是有效数据,demoArray[10]才是无效的数据
          return 0;
          }??
    • find_if Find element in range (function template ) 在一个范围里面查找元素
      • 观察本质
        template<class InputIterator, class UnaryPredicate>
        InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred)
        {
        while (first!=last) {
        if (pred(*first)) return first; //返回第一个符合条件的元素。
        ++first;
        }
        return last;
        }
        ----------------------------------------------------------------------------------------
        // find_if example
        #include <iostream> // std::cout
        #include <algorithm> // std::find_if
        #include <vector> // std::vector
        bool IsOdd (int i) {
        return ((i%2)==1);
        }
        int main () {
        std::vector<int> myvector;
        myvector.push_back(10);
        myvector.push_back(25);
        myvector.push_back(40);
        myvector.push_back(55);
        std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
        std::cout << "The first odd value is " << *it << ‘\n‘;
        return 0;
        }

        ----------------------------------------------------------------------------------------------

        Output:
        The first odd value is 25

        解释:返回第一个符合条件的元素。如果没有找到,则返回有效区间+1的无效数据位置。
        ?
        ???????
        ???
    • find_if_not  Find element in range (negative condition 否定条件) (function template )
      • 观察本质
        template<class InputIterator, class UnaryPredicate>
        InputIterator find_if_not (InputIterator first, InputIterator last, UnaryPredicate pred)
        {
        while (first!=last) {
        if (!pred(*first)) return first; //返回第一个不符合要求的元素
        ++first;
        }
        return last;
        }
        -----------------------------------------------------------------------------------------------
        // find_if_not example
        #include <iostream> // std::cout
        #include <algorithm> // std::find_if_not
        #include <array> // std::array

        int main () {
        std::array<int,5> foo = {1,2,3,4,5};

        std::array<int,5>::iterator it =
        std::find_if_not (foo.begin(), foo.end(), [](int i){return i%2;} );
        std::cout << "The first even value is " << *it << ‘\n‘;

        return 0;
        }

        ---------------------------------------------------------------------------------------------------
        ???Output:
        The first even value is 2

        解释:在一个范围内查找不符合要求的元素,返回第一个不符合要求的元素。
        ???
        ???
    • find_end Find last subsequence in range (function template )
      • 观察本质
        template<class ForwardIterator1, class ForwardIterator2> //只写了带4个参数的实现
        ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1,
        ForwardIterator2 first2, ForwardIterator2 last2)
        {
        if (first2==last2) return last1; // specified in C++11 判断第2区间是否有效

        ForwardIterator1 ret = last1;

        while (first1!=last1) //遍历第1区间
        {
        ForwardIterator1 it1 = first1;
        ForwardIterator2 it2 = first2;
        while (*it1==*it2) { // or: while (pred(*it1,*it2)) for version (2)
        ++it1; ++it2; //用临时it变量对比,第1区间每个元素,与第2区间的每个元素
        if (it2==last2) { ret=first1; break; } //判断第2区间是否遍历完,完成了则重置要返回的值,跳出此内循环
        if (it1==last1) return ret; //判断第1区间是否遍历完,完成了返回第1区间末尾加一位置
        }
        ++first1;
        }
        return ret;
        }
        ---------------------------------------------------------------------------------------
        // find_end example
        #include <iostream> // std::cout
        #include <algorithm> // std::find_end
        #include <vector> // std::vector
        bool myfunction (int i, int j) {
        return (i==j);
        }
        int main () {
        int myints[] = {1,2,3,4,5,1,2,3,4,5};
        std::vector<int> haystack (myints,myints+10);
        ?
        int needle1[] = {1,2,3};?
        // using default comparison:
        std::vector<int>::iterator it;
        it = std::find_end (haystack.begin(), haystack.end(), needle1, needle1+3);
        if (it!=haystack.end())
        std::cout << "needle1 last found at position " << (it-haystack.begin()) << ‘\n‘;
        ?
        int needle2[] = {4,5,1};?
        // using predicate comparison:
        it = std::find_end (haystack.begin(), haystack.end(), needle2, needle2+3, myfunction);
        if (it!=haystack.end())
        std::cout << "needle2 last found at position " << (it-haystack.begin()) << ‘\n‘;
        ?
        return 0;
        }
        ------------------------------------------------------------------------------------------------
        Output:
        needle1 found at position 5
        needle2 found at position 3

        解释:
        1 函数重载,一个4参数,一个5参数,后面多一个BinaryPredicate pred ?????(二元谓词)
        2 算法功能:在第1区间查找,是否与第2区间完全匹配,匹配成功返回第1空间匹配最后的元素。简单来说:就是查找某一段数据。
        3 ??注意点:数据如果不是在前闭后开的容器中(如:数组),都要注意最后的元素的设定。
        ----------------------------------------vs2015代码-----------------------------------------
        // TEMPLATE FUNCTION find_end WITH PRED
        template<class _FwdIt1, class _FwdIt2, class _Pr> inline
        _FwdIt1 _Find_end_unchecked(_FwdIt1 _First1, _FwdIt1 _Last1,
        _FwdIt2 _First2, _FwdIt2 _Last2, _Pr& _Pred)
        { // find last [_First2, _Last2) satisfying _Pred
        _Iter_diff_t<_FwdIt1> _Count1 = _STD distance(_First1, _Last1); //区间距离1
        _Iter_diff_t<_FwdIt2> _Count2 = _STD distance(_First2, _Last2); //区间距离2
        _FwdIt1 _Ans = _Last1;

        if (0 < _Count2)
        { // validate _Pred and test
        _DEBUG_POINTER_IF(_Count2 <= _Count1, _Pred);
        for (; _Count2 <= _Count1; ++_First1, (void)--_Count1)
        { // room for match, try it
        _FwdIt1 _Mid1 = _First1;
        for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1)
        if (!_Pred(*_Mid1, *_Mid2))
        break;
        else if (++_Mid2 == _Last2)
        { // potential answer, save it
        _Ans = _First1;
        break;
        }
        }
        }

        return (_Ans);
        }??
        ???
    • find_first_of Find element from set in range (function template ) 从设定范围内查找元素
      • 观察本质
        template<class InputIterator, class ForwardIterator>
        InputIterator find_first_of ( InputIterator first1, InputIterator last1,
        ForwardIterator first2, ForwardIterator last2)
        {
        while (first1!=last1) {
        for (ForwardIterator it=first2; it!=last2; ++it) {
        if (*it==*first1) // or: if (pred(*it,*first)) for version (2)
        return first1;
        }
        ++first1;
        }
        return last1;
        }
        --------------------------------------------------------------------------------------------
        // find_first_of example
        #include <iostream> // std::cout
        #include <algorithm> // std::find_first_of
        #include <vector> // std::vector
        #include <cctype> // std::tolower

        bool comp_case_insensitive (char c1, char c2) {
        return (std::tolower(c1)==std::tolower(c2));
        }

        int main () {
        int mychars[] = {‘a‘,‘b‘,‘c‘,‘A‘,‘B‘,‘C‘};
        std::vector<char> haystack (mychars,mychars+6);
        std::vector<char>::iterator it;

        int needle[] = {‘A‘,‘B‘,‘C‘};

        // using default comparison:
        it = find_first_of (haystack.begin(), haystack.end(), needle, needle+3);

        if (it!=haystack.end())
        std::cout << "The first match is: " << *it << ‘\n‘;

        // using predicate comparison:
        it = find_first_of (haystack.begin(), haystack.end(),
        needle, needle+3, comp_case_insensitive);

        if (it!=haystack.end())
        std::cout << "The first match is: " << *it << ‘\n‘;

        return 0;
        }
        ----------------------------------------------------------------------------------------
        Output:
        The first match is: A
        The first match is: a

        解释:
        循环区间1,里面嵌套循环区间2,用临时it比较所有元素,相等(或其它条件)则直接返回区间1此时元素.
        简单来说:就是查找任意一个相同(或者其它条件)元素,即刻返回。?

        ---------------------------------------------vs2015--------------------------------------
        // TEMPLATE FUNCTION find_first_of WITH PRED
        template<class _FwdIt1, class _FwdIt2, class _Pr> inline
        _FwdIt1 _Find_first_of_unchecked(_FwdIt1 _First1, _FwdIt1 _Last1,
        _FwdIt2 _First2, _FwdIt2 _Last2, _Pr& _Pred)
        { // look for one of [_First2, _Last2) satisfying _Pred with element
        for (; _First1 != _Last1; ++_First1)
        for (_FwdIt2 _Mid2 = _First2; _Mid2 != _Last2; ++_Mid2)
        if (_Pred(*_First1, *_Mid2))
        return (_First1);
        return (_First1);
        }??????
        ???
        ???
    • adjacent_find Find equal adjacent elements in range (function template ) 在范围内查找相等的相邻元素
      • 观察本质
        template <class ForwardIterator>
        ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last)
        {
        if (first != last)
        {
        ForwardIterator next=first; ++next; //跳过第1个元素
        while (next != last) {
        if (*first == *next) // or: if (pred(*first,*next)), for version (2) 比较第1个和第2个元素
        return first; //如符合条件,直接返回first
        ++first; ++next; //不符合条件,则轮番向前
        }
        }
        return last;
        }
        ---------------------------------------------------------------------------------------
        // adjacent_find example
        #include <iostream> // std::cout
        #include <algorithm> // std::adjacent_find
        #include <vector> // std::vector

        bool myfunction (int i, int j) {
        return (i==j);
        }

        int main () {
        int myints[] = {5,20,5,30,30,20,10,10,20};
        std::vector<int> myvector (myints,myints+8);
        std::vector<int>::iterator it;

        // using default comparison:
        it = std::adjacent_find (myvector.begin(), myvector.end());

        if (it!=myvector.end())
        std::cout << "the first pair of repeated elements are: " << *it << ‘\n‘;

        //using predicate comparison:
        it = std::adjacent_find (++it, myvector.end(), myfunction);

        if (it!=myvector.end())
        std::cout << "the second pair of repeated elements are: " << *it << ‘\n‘;

        return 0;
        }
        -------------------------------------------------------------------------------------------
        Output:
        the first pair of repeated elements are: 30
        the second pair of repeated elements are: 10

        解释:


        ------------------------------------vs2015-----------------------------------------------
        // TEMPLATE FUNCTION adjacent_find WITH PRED
        template<class _FwdIt,
        class _Pr> inline
        _FwdIt _Adjacent_find_unchecked(_FwdIt _First, _FwdIt _Last, _Pr& _Pred)
        { // find first satisfying _Pred with successor
        if (_First != _Last)
        for (_FwdIt _Firstb; (void)(_Firstb = _First), ++_First != _Last; )
        if (_Pred(*_Firstb, *_First))
        return (_Firstb);
        return (_Last);
        }????????

        ????
    • count Count appearances of value in range (function template ) 计数
      • 观察本质
        template <class InputIterator, class UnaryPredicate>
        typename iterator_traits<InputIterator>::difference_type
        count_if (InputIterator first, InputIterator last, UnaryPredicate pred)
        {
        typename iterator_traits<InputIterator>::difference_type ret = 0;
        while (first!=last) {
        if (pred(*first)) ++ret;
        ++first;
        }
        return ret;
        }
        -------------------------------------------------------------------------------------
        // count_if example
        #include <iostream> // std::cout
        #include <algorithm> // std::count_if
        #include <vector> // std::vector

        bool IsOdd (int i) { return ((i%2)==1); }

        int main () {
        std::vector<int> myvector;
        for (int i=1; i<10; i++) myvector.push_back(i); // myvector: 1 2 3 4 5 6 7 8 9

        int mycount = count_if (myvector.begin(), myvector.end(), IsOdd);
        std::cout << "myvector contains " << mycount << " odd values.\n";

        return 0;
        }
        ---------------------------------------------------------------------------------------------
        Output:
        myvector contains 5 odd values.

        解释:计数算法

        -------------------------------------------vs2015--------------------------------------------
        // TEMPLATE FUNCTION count
        template<class _InIt,
        class _Ty> inline
        _Iter_diff_t<_InIt>
        _Count_unchecked(_InIt _First, _InIt _Last, const _Ty& _Val)
        { // count elements that match _Val
        _Iter_diff_t<_InIt> _Count = 0;

        for (; _First != _Last; ++_First)
        if (*_First == _Val)
        ++_Count;
        return (_Count);
        }
        ??????????
    • count_if Return number of elements in range satisfying condition (function template ) 按条件计数
      • 观察本质
        template <class InputIterator, class UnaryPredicate>
        typename iterator_traits<InputIterator>::difference_type
        count_if (InputIterator first, InputIterator last, UnaryPredicate pred)
        {
        typename iterator_traits<InputIterator>::difference_type ret = 0;
        while (first!=last) {
        if (pred(*first)) ++ret;
        ++first;
        }
        return ret;
        }
        ------------------------------------------------------------------------------------
        // count_if example
        #include <iostream> // std::cout
        #include <algorithm> // std::count_if
        #include <vector> // std::vector

        bool IsOdd (int i) { return ((i%2)==1); }

        int main () {
        std::vector<int> myvector;
        for (int i=1; i<10; i++) myvector.push_back(i); // myvector: 1 2 3 4 5 6 7 8 9

        int mycount = count_if (myvector.begin(), myvector.end(), IsOdd);
        std::cout << "myvector contains " << mycount << " odd values.\n";

        return 0;
        }
        -----------------------------------------------------------------------------------

        Output:
        myvector contains 5 odd values.

        解释:按条件计数


        -------------------------------------------------vs2015--------------------------

        ????????????
    • mismatch Return first position where two ranges differ (function template ) 返回两个范围不同的第一位置
      • 观察本质
        template <class InputIterator1, class InputIterator2>
        pair<InputIterator1, InputIterator2>
        mismatch (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 )
        {
        while ( (first1!=last1) && (*first1==*first2) ) // or: pred(*first1,*first2), for version 2
        { ++first1; ++first2; }
        return std::make_pair(first1,first2);
        }
        ----------------------------------------------------------------------------------------------
        // mismatch algorithm example
        #include <iostream> // std::cout
        #include <algorithm> // std::mismatch
        #include <vector> // std::vector
        #include <utility> // std::pair

        bool mypredicate (int i, int j) {
        return (i==j);
        }

        int main () {
        std::vector<int> myvector;
        for (int i=1; i<6; i++) myvector.push_back (i*10); // myvector: 10 20 30 40 50

        int myints[] = {10,20,80,320,1024}; // myints: 10 20 80 320 1024

        std::pair<std::vector<int>::iterator,int*> mypair;

        // using default comparison:
        mypair = std::mismatch (myvector.begin(), myvector.end(), myints);
        std::cout << "First mismatching elements: " << *mypair.first;
        std::cout << " and " << *mypair.second << ‘\n‘;

        ++mypair.first; ++mypair.second;

        // using predicate comparison:
        mypair = std::mismatch (mypair.first, myvector.end(), mypair.second, mypredicate);
        std::cout << "Second mismatching elements: " << *mypair.first;
        std::cout << " and " << *mypair.second << ‘\n‘;

        return 0;
        }
        -------------------------------------------------------------------------------------------------------------
        Output:
        First mismatching elements: 30 and 80
        Second mismatching elements: 40 and 320

        解释:


        ---------------------------------------vs2015--------------------------------------------------\
        // TEMPLATE FUNCTION mismatch
        template<class _InIt1,class _InIt2> inline
        pair<_InIt1, _InIt2>
        mismatch(_InIt1 _First1, _InIt1 _Last1,
        _InIt2 _First2)
        { // return [_First1, _Last1)/[_First2, ...) mismatch
        return (_STD mismatch(_First1, _Last1, _First2,
        equal_to<>()));
        }?????
        -------------------------------------------------------------------------------------------------------、
        // TEMPLATE FUNCTION mismatch WITH PRED
        template<class _InIt1,class _InIt2, class _Pr> inline
        pair<_InIt1, _InIt2>
        _Mismatch_unchecked(_InIt1 _First1, _InIt1 _Last1,
        _InIt2 _First2, _Pr& _Pred)
        { // return [_First1, _Last1)/[_First2, ...) mismatch using _Pred
        for (; _First1 != _Last1 && _Pred(*_First1, *_First2); )
        { // point past match
        ++_First1;
        ++_First2;
        }

        return (pair<_InIt1, _InIt2>(_First1, _First2));
        }????
        ??????
    • equal Test whether the elements in two ranges are equal (function template )
      • 观察本质
        template <class InputIterator1, class InputIterator2>
        bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 )
        {
        while (first1!=last1) {
        if (!(*first1 == *first2)) // or: if (!pred(*first1,*first2)), for version 2
        return false;
        ++first1; ++first2; //第2区间没有判断条件
        }
        return true;
        }
        --------------------------------------------------------------------------------------------
        // equal algorithm example
        #include <iostream> // std::cout
        #include <algorithm> // std::equal
        #include <vector> // std::vector

        bool mypredicate (int i, int j) {
        return (i==j);
        }

        int main () {
        int myints[] = {20,40,60,80,100}; // myints: 20 40 60 80 100
        std::vector<int>myvector (myints,myints+5); // myvector: 20 40 60 80 100

        // using default comparison:
        if ( std::equal (myvector.begin(), myvector.end(), myints) )
        std::cout << "The contents of both sequences are equal.\n";
        else
        std::cout << "The contents of both sequences differ.\n";

        myvector[3]=81; // myvector: 20 40 60 81 100

        // using predicate comparison:
        if ( std::equal (myvector.begin(), myvector.end(), myints, mypredicate) )
        std::cout << "The contents of both sequences are equal.\n";
        else
        std::cout << "The contents of both sequences differ.\n";

        return 0;
        }
        ----------------------------------------------------------------------------------------
        Output:
        The contents of both sequences are equal.
        The contents of both sequence differ.

        解释:第2区间要保证比第1区间要长,不然会出问题。

        -------------------------------------------------vs2015---------------------------------

        // TEMPLATE FUNCTION equal WITH TWO RANGES, PRED
        template<class _InIt1,class _InIt2,class _Pr> inline
        bool _Equal_unchecked(_InIt1 _First1, _InIt1 _Last1,
        _InIt2 _First2, _InIt2 _Last2, _Pr& _Pred,
        input_iterator_tag, input_iterator_tag)
        { // compare [_First1, _Last1) to [_First2, _Last2)
        // using _Pred, arbitrary iterators
        _DEBUG_POINTER_IF(_First1 != _Last1 && _First2 != _Last2, _Pred);
        for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, (void)++_First2)
        if (!_Pred(*_First1, *_First2))
        return (false);
        return (_First1 == _Last1 && _First2 == _Last2);
        }??????
        ?????
    • is_permutation  Test whether range is permutation of another (function template ) 测试范围是否是另一个排列
      • 观察本质
        template <class InputIterator1, class InputIterator2>
        bool is_permutation (InputIterator1 first1, InputIterator1 last1,
        InputIterator2 first2)
        {
        std::tie (first1,first2) = std::mismatch (first1,last1,first2);
        if (first1==last1) return true;
        InputIterator2 last2 = first2; std::advance (last2,std::distance(first1,last1));
        for (InputIterator1 it1=first1; it1!=last1; ++it1) {
        if (std::find(first1,it1,*it1)==it1) {
        auto n = std::count (first2,last2,*it1);
        if (n==0 || std::count (it1,last1,*it1)!=n) return false;
        }
        }
        return true;
        }
        -----------------------------------------------------------------------------------------
        // is_permutation example
        #include <iostream> // std::cout
        #include <algorithm> // std::is_permutation
        #include <array> // std::array

        int main () {
        std::array<int,5> foo = {1,2,3,4,5};
        std::array<int,5> bar = {3,1,4,5,2};

        if ( std::is_permutation (foo.begin(), foo.end(), bar.begin()) )
        std::cout << "foo and bar contain the same elements.\n";

        return 0;
        }
        ------------------------------------------------------------------------------------------------
        Output:
        foo and bar contain the same elements.

        解释:是否是一组有序的排列

        ------------------------------------------vs2015-------------------------------------------

        // TEMPLATE FUNCTION is_permutation WITH PRED
        template<class _FwdIt1,
        class _FwdIt2,
        class _Pr> inline
        bool _Is_permutation_unchecked(_FwdIt1 _First1, _FwdIt1 _Last1,
        _FwdIt2 _First2, _Pr& _Pred)
        { // test if [_First1, _Last1) == permuted [_First2, ...), using _Pred
        for (; _First1 != _Last1; ++_First1, (void)++_First2)
        if (!_Pred(*_First1, *_First2))
        { // found first inequality, check match counts in suffix
        _FwdIt2 _Last2 = _STD next(_First2,
        _STD distance(_First1, _Last1));
        return (_Check_match_counts(_First1, _Last1,
        _First2, _Last2, _Pred));
        }

        return (true);
        }?
        ??????????
    • search Search range for subsequence (function template ) 搜索 标准的范围查找 对应 find_end
      • 观察本质
        template<class ForwardIterator1, class ForwardIterator2>
        ForwardIterator1 search ( ForwardIterator1 first1, ForwardIterator1 last1,
        ForwardIterator2 first2, ForwardIterator2 last2)
        {
        if (first2==last2) return first1; // specified in C++11

        while (first1!=last1)
        {
        ForwardIterator1 it1 = first1;
        ForwardIterator2 it2 = first2;
        while (*it1==*it2) { // or: while (pred(*it1,*it2)) for version 2
        ++it1; ++it2;
        if (it2==last2) return first1;
        if (it1==last1) return last1;
        }
        ++first1;
        }
        return last1;
        }
        ---------------------------------------------------------------------------------
        // search algorithm example
        #include <iostream> // std::cout
        #include <algorithm> // std::search
        #include <vector> // std::vector

        bool mypredicate (int i, int j) {
        return (i==j);
        }

        int main () {
        std::vector<int> haystack;

        // set some values: haystack: 10 20 30 40 50 60 70 80 90
        for (int i=1; i<10; i++) haystack.push_back(i*10);

        // using default comparison:
        int needle1[] = {40,50,60,70};
        std::vector<int>::iterator it;
        it = std::search (haystack.begin(), haystack.end(), needle1, needle1+4);

        if (it!=haystack.end())
        std::cout << "needle1 found at position " << (it-haystack.begin()) << ‘\n‘;
        else
        std::cout << "needle1 not found\n";

        // using predicate comparison:
        int needle2[] = {20,30,50};
        it = std::search (haystack.begin(), haystack.end(), needle2, needle2+3, mypredicate);

        if (it!=haystack.end())
        std::cout << "needle2 found at position " << (it-haystack.begin()) << ‘\n‘;
        else
        std::cout << "needle2 not found\n";

        return 0;
        }
        ---------------------------------------------------------------------------------------------
        Output:
        needle1 found at position 3
        needle2 not found

        解释:

        -------------------------------------vs2015------------------------------------------------
        // TEMPLATE FUNCTION search WITH PRED
        template<class _FwdIt1, class _FwdIt2, class _Pr> inline
        _FwdIt1 _Search_unchecked(_FwdIt1 _First1, _FwdIt1 _Last1,
        _FwdIt2 _First2, _FwdIt2 _Last2, _Pr& _Pred,
        forward_iterator_tag, forward_iterator_tag)
        { // find first [_First2, _Last2) satisfying _Pred, arbitrary iterators
        for (; ; ++_First1)
        { // loop until match or end of a sequence
        _FwdIt1 _Mid1 = _First1;
        for (_FwdIt2 _Mid2 = _First2; ; ++_Mid1, (void)++_Mid2)
        if (_Mid2 == _Last2)
        return (_First1);
        else if (_Mid1 == _Last1)
        return (_Last1);
        else if (!_Pred(*_Mid1, *_Mid2))
        break;
        }
        }?????????
    • search_n Search range for elements (function template )
      • 观察本质
        template<class ForwardIterator, class Size, class T>
        ForwardIterator search_n (ForwardIterator first, ForwardIterator last,
        Size count, const T& val)
        {
        ForwardIterator it, limit;
        ? Size i;

        limit=first; std::advance(limit,std::distance(first,last)-count);

        while (first!=limit)
        {
        it = first; i=0;
        while (*it==val) // or: while (pred(*it,val)) for the pred version
        { ++it; if (++i==count) return first; }
        ++first;
        }
        return last;
        }
        -------------------------------------------------------------------------------------
        // search_n example
        #include <iostream> // std::cout
        #include <algorithm> // std::search_n
        #include <vector> // std::vector

        bool mypredicate (int i, int j) {
        return (i==j);
        }

        int main () {
        int myints[]={10,20,30,30,20,10,10,20};
        std::vector<int> myvector (myints,myints+8);

        std::vector<int>::iterator it;

        // using default comparison:
        it = std::search_n (myvector.begin(), myvector.end(), 2, 30);

        if (it!=myvector.end())
        std::cout << "two 30s found at position " << (it-myvector.begin()) << ‘\n‘;
        else
        std::cout << "match not found\n";

        // using predicate comparison:
        it = std::search_n (myvector.begin(), myvector.end(), 2, 10, mypredicate);

        if (it!=myvector.end())
        std::cout << "two 10s found at position " << int(it-myvector.begin()) << ‘\n‘;
        else
        std::cout << "match not found\n";

        return 0;
        }
        ------------------------------------------------------------------------------------------
        Output:
        Two 30s found at position 2
        Two 10s found at position 5

        解释:##advance
        template <class InputIterator, class Distance>
        void advance (InputIterator& it, Distance n);
        迭代器辅助函数。
        使迭代器it偏移n,其中n为整数。?
        -----------------------------advance-----------------------
        ?
        #include <iostream> // std::cout
        #include <iterator> // std::advance
        #include <list> // std::list

        int main () {
        std::list<int> mylist;
        for (int i=0; i<10; i++) mylist.push_back (i*10);

        std::list<int>::iterator it = mylist.begin();

        std::advance (it,5);
        std::cout << "The sixth element in mylist is: " << *it << ‘\n‘;

        std::advance (it,-1);
        std::cout << "The fifth element in mylist is: " << *it << ‘\n‘;

        return 0;
        }?
        -------------------------advnce Deom output---------------------
        The sixth element in mylist is: 50
        The fifth element in mylist is: 40??
        ?
        ?????
        --------------------------------------vs2015-search_n--------------------------------------
        ?
        // TEMPLATE FUNCTION search_n WITH PRED
        template<class _FwdIt,class _Diff,class _Ty,class _Pr> inline
        _FwdIt _Search_n_unchecked(_FwdIt _First, _FwdIt _Last,
        _Diff _Count, const _Ty& _Val, _Pr& _Pred, forward_iterator_tag)
        { // find first _Count * _Val satisfying _Pred, forward iterators
        if (_Count <= 0)
        return (_First);

        for (; _First != _Last; ++_First)
        if (_Pred(*_First, _Val))
        { // found start of possible match, check it out
        _FwdIt _Mid = _First;

        for (_Diff _Count1 = _Count; ; )
        if (--_Count1 == 0)
        return (_First); // found rest of match, report it
        else if (++_Mid == _Last)
        return (_Last); // short match at end
        else if (!_Pred(*_Mid, _Val))
        { // short match not at end
        break;
        }

        _First = _Mid; // pick up just beyond failed match
        }

        return (_Last);
        }????
    • 非变动型算法分类:
      • 算法 粗略分类0
        • 1 不带后缀
          • 基本上算法的主要功能,在语义上表示出来。
            如:find count equal search
        • 2 带后缀
          • xxx_of of带有“如果”的意义,此种带“of”后缀的算法,一定会带一个函数,来进行判断,返回一个bool值。all_of功能就是:判断容器里面全部数据是不是一个什么(of).如果是则返回true,否则返回faulse.
          • xxx_if if带有“判断条件”的意义
      • 算法 粗略分类1
        • 搜索
          search
          search_n?
        • 查找
          find
          find_if
          find_if_not
          find_end
          find_first_of????
        • 是否相等(相同)
          equal?
          mismatch?
        • 是否同一组
          is_permutation
        • 计数
          count
          count_if?
    • 小结:非变动型算法
      1 all_of any_of none_of这3个主要功能:用来测试,测试在容器中有没有符合条件的数据。
      2 ?for_each主要功能:巡访、遍历,具体是否改变,由程序员决定。
      3 ?搜索查找系列:find find_if find_if_not find_end find_first_of search search_n ##“搜查七种武器
      find:值的查找 find_if 符合条件的查找 find_if_not 符合条件的查找取反 ?find_end 最后一个的、一整块符合条件的查找 find_first_of 查找符合条件的第一个元素 search 搜查最前一个的、一整块符合条件的 search_n 搜查一定偏移量的区间,查找符合特定条件的。
      4 ?统计计数count count_if
      5 比较 equal等。?
      ?

以上是关于STL (13) 非变动型算法的主要内容,如果未能解决你的问题,请参考以下文章

stl_algorithm算法之变动性算法和非动性算法

[GeekBand] STL与泛型编程

STL非变易算法

STL 优先队列的自定义比较函数与 sort() 等泛型算法的自定义比较函数的区别

C++ STL学习 —— 模板泛型算法函数对象lambda 表达式(参数捕获)函数适配器

C++ STL学习 —— 模板泛型算法函数对象lambda 表达式(参数捕获)函数适配器