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等。​

转载于:https://www.cnblogs.com/bing-z/p/6740301.html

STL (13) 非变动型算法相关推荐

  1. 二叉树的中序遍历非递归方法(算法导论第三版12.1-3)

    二叉树的中序遍历非递归方法(算法导论第三版12.1-3) 1⃣️用栈实现 template<typename T> void inorder_tree_walk_non_recursion ...

  2. 基于STL实现自动贪心寻路算法的贪吃蛇小游戏

    基于STL实现自动贪心寻路算法的贪吃蛇小游戏 写贪吃蛇小游戏的想法来自CometOJ-Contest#13的B题,当时用STL双端队列维护蛇身的时候觉得非常方便,现在用EasyX图形库实现一下. 运行 ...

  3. 一文清晰讲解机器学习中梯度下降算法(包括其变式算法)

    本篇文章向大家介绍梯度下降(Gradient Descent)这一特殊的优化技术,我们在机器学习中会频繁用到. 前言 无论是要解决现实生活中的难题,还是要创建一款新的软件产品,我们最终的目标都是使其达 ...

  4. 照片美妆--人像变老算法研究

    人像变老技术可以把一张小孩子的照片或者年轻人的照片转换为变老以后的样子,目前市面上已有相应的应用,这里本人先放两张效果,然后分析算法: 这个效果是本人算法的效果,现在我们来分析一下人像变老的技术情况. ...

  5. 非极大值抑制算法hard-NMS与soft-NMS

    前言 非极大值抑制算法(Non-maximum suppression, NMS)是有anchor系列目标检测的标配,如今大部分的One-Stage和Two-Stage算法在推断(Inference) ...

  6. SoundTouch与Rubber Band Library变声算法对比与ASR结果分析

    详细内容见群文件,欢迎大家加入音频/识别/合成算法群(696554058)交流学习,谢谢! 本内容原创,转载和使用请注明出处,谢谢配合: 变声背景与目的 目前基于对语音识别数据收集缓慢且质量不高的情况 ...

  7. 字典序全排列算法(非递归全排列算法)

    非递归全排列算法: 我们先看一个例子. 示例: 1 2 3的全排列如下: 1 2 3 , 1 3 2 , 2 1 3 , 2 3 1 , 3 1 2 , 3 2 1 我们这里是通过字典序法找出来的. ...

  8. STL常用的算术和生成算法

    STL常用的算术和生成算法 accumulate() fill() accumulate() accumulate: 对指定范围内的元素求和,然后结果再加上一个由val指定的初始值. #include ...

  9. 树:二叉树的非递归遍历算法

    二叉树的递归遍历 二叉树的递归遍历算法,写法很简单,比如说前序遍历树,如下: //前序遍历 void PreOrderTraverse(BiTree tree) {if (NULL != tree){ ...

最新文章

  1. win7无法连接打印机拒绝访问_win7系统连接XP网络打印机无法连接到打印机拒绝访问的解决方法...
  2. 20051020:该办宽带了
  3. linux python2.7 链接mysql导出数据库脚本_python备份文件以及mysql数据库的脚本代码...
  4. 如果有一天,小夕不再萌...
  5. mysql 回滚_一个集审核、执行、备份及生成回滚语句于一身的MySQL运维工具
  6. VS2013 生成sqlite3动态连接库
  7. C++,next_permutation(start_array_index,end_index)的使用
  8. python 面向对象编程、别人么样用_Python 中的面向对象没有意义
  9. 计算机类教材的选题策划,电子计算机类科技期刊的选题策划.doc
  10. iText实现html转pdf
  11. Vue核心技术-39,vue-router-向路由组件传递数据
  12. csgo连接到任意官方服务器失败删除文件,CSGO连接到官方任意服务器失败怎么办...
  13. 技术中台的作用是什么,在什么情况下才有必要做技术中台?
  14. deep learning编程作业总结1---喵咪识别
  15. python中的海归制图(turtle)绘制文字
  16. 【CSDN云VS腾讯云】要不然怎么说CSDN开发云是打工人和学生党的福音呢?
  17. chrom调试技巧大全,史上最全
  18. 电子沙盘系统android,交互式军事电子沙盘系统
  19. IAR MSP430头文件中的一些解释
  20. 二维动画设计软件应用——Flash CS6全书电子教案完整版电子教案

热门文章

  1. 一个支付案例,学会策略模式!
  2. 聊一聊 软件系统中的“热力学第二定律”
  3. G1的Region是如何划分数量和大小的?
  4. 一个基于SpringBoot + Mybatis + Vue的代码生成器
  5. 跟我学Springboot开发后端管理系统6:缓存框架Caffeine
  6. 为什么SpringBoot的 jar 可以直接运行?
  7. 面试官给我挖坑:URI中的 “//” 有什么用?
  8. 吴恩达新书《Machine Learning Yearning》完整中文版 PDF 下载!
  9. 哈工大导师禁止实验室硕士出去实习,称「实习就像和35岁渣男试婚」,你怎么看?...
  10. 详解Batch Normalization及其反向传播