首页 > 代码库 > stl_algorithm算法之变动性算法和非动性算法

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

七、算法:(算法头文件:<algorithm>)

  所有的算法都需要iterator的支持,列如支持++,*,op=,op==,等等。。

非变动性算法:

7.1、template<class InputIterator, class UnaryPredicate>
bool all_of (InputIterator first, InputIterator last, UnaryPredicate pred) //要所有的数据都是符合当前的条件才回返回TRUE,否则FALSE。
{
  while (first!=last) { //进行整个区间的遍历。
    if (!pred(*first)) return false; //但凡有一个不符合条件的就返回FALSE
    ++first;
  }
  return true;
}
//所做的事情是:判断区间中的所有元素是否都是符合pred函数中指定的条件的元素。

匿名函数: [](int i){return i%2;} //这是一个匿名函数。[]代表之后是匿名函数、(int i)是参数列表、{return i%2}是函数体。

  //即用既抛, 只能在当前位置使用,这种函数经常会和算法函数结合进行使用。

7.2、template<class InputIterator, class UnaryPredicate>
bool any_of (InputIterator first, InputIterator last, UnaryPredicate pred) //和all_of正好是相反的。
{
  while (first!=last) {
    if (pred(*first)) return true; //只要有一个符合条件就返回TRUE
    ++first;
  }
  return false;
}
//所做的事情是:判断区间中是否有元素符合pred函数中指定的条件的元素。

 

7.3、template<class InputIterator, class UnaryPredicate>
bool none_of (InputIterator first, InputIterator last, UnaryPredicate pred) //需要任何元素都是不符合当前条件的才回返回TRUE,否则FALSE
{
  while (first!=last) {
    if (pred(*first)) return false; //有一个符合的就返回FALSE
    ++first;
  }
  return true;
}
//所做的事情是:判断区间中是否都是不符合pred函数中指定条件的元素。

 

7.4、template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn)
{
  while (first!=last) {
    fn (*first); //fn函数做指定的操作。
    ++first;
  }
  return fn; // or, since C++11: return move(fn);
}
//所做的事情是:将区间中的元素放入fn函数中完成一些指定的操作。

 

7.5、template<class InputIterator, class T>
InputIterator find (InputIterator first, InputIterator last, const T& val)
{
  while (first!=last) {
    if (*first==val) return first; //找到val 所在区间的第一个的位置。
    ++first;
  }
  return last; //如果没有能找到就返回last。
}
//所做的事情是:寻找val元素的位置。
//此时的val 不一定要和first,last中的type_value是一样的,只要是进行了==操作符的重载就可以。
//换句话说就是在这个区间内必须支持和val的 "==" 操作。
//而 "==" 操作 在默认类中是没有的,所以这个 "==" 操作符必须进行==符的重载。

 

7.6、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; //如果没有能找到就返回last。
}
//所做的事情是:找到区间中符合pred函数指定条件的第一个元素。

 

7.7、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;
}
//所做的事情是:找到区间中不符合pred函数指定条件的一个元素。

 

7.8、template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1,
                ForwardIterator2 first2, ForwardIterator2 last2)
{
  if (first2==last2) return last1; //如果第二个区间为空就直接返回第一个区间的last。
  ForwardIterator1 ret = last1;
  while (first1 != last1) //首先对第一个区间进行遍历。
  {
    ForwardIterator1 it1 = first1;
    ForwardIterator2 it2 = first2;
    while (*it1 == *it2) { 
      ++it1; ++it2;
      if (it2==last2) { ret=first1; break; }//当第二个区间遍历完成就break
      if (it1==last1) return ret; //当第一个区间遍历完就直接return ret。
    }
    ++first1;
  }
  return ret;
}
//所做的事情是:返回第一个区间中符合第二个区间在第一个区间中的最后一个位置
//的第一个元素的地址。 前提的条件是第一个区间存在完全吻合第二个区间的元素。

 

7.9、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;
}
//所做的事情是:找到符合第二个区间中第一个区间的第一个元素。

 

7.10、template <class ForwardIterator>
ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last)
{
  if (first != last)
  {
    ForwardIterator next = first; ++next;
    while (next != last) {
      if (*first == *next) // or: if (pred(*first,*next)), for version (2)
        return first; //找到相邻的且相等的两个,返回第一个。
      ++first; ++next;
    }
  }
  return last;
}
//所做的事情是:找到第一个相邻且相等的两个元素,返回这两个数的第一个元素。

 

7.11、template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count (InputIterator first, InputIterator last, const T& val)
{
  typename iterator_traits<InputIterator>::difference_type ret = 0;
  while (first!=last) {
    if (*first == val) ++ret;//遍历中若是发现与val相等的元素就对ret进行++
    ++first;
  }
  return ret;
}
//所做的事情是:获得区间中有多少个和val相等的元素。

 

7.12、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;//满足pred函数中指定条件的元素,就对ret进行++。
    ++first;
  }
  return ret;
}
//所做的事情是:返回区间中有多少个符合pred函数的元素个数。

 

7.13、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); //返回找到的一对。
}
//所做的事情是:返回两个区间第一对不相等的两个元素。

 

7.14、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; //如果发现有一个元素不想等的话就返回FALSE。
    ++first1; ++first2;
  }
  return true; //两个区间完全相同才回返回TRUE。
}
//所做的事情是:判断两个区间是否是都是相同的。

 

7.15、template <class InputIterator1, class InputIterator2> //!!!!!!!!!!!1
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;
}

 

7.16、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;
}
//所做的事情是:判断第二个区间是否在第一个区间中找到。

 

7.17、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;
}

 

7.18、template<class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
  while (first != last) {
    *result = *first; //调用op=
    ++result; ++first; //都偏移
  }
  return result; //返回复制之后的新地址。
}
//所做的事情是:将区间中的元素复制到result这段空间中。

 

7.19、template<class InputIterator, class Size, class OutputIterator>
OutputIterator copy_n (InputIterator first, Size n, OutputIterator result)
{
  while (n>0) { //只是复制区间中的前n个。
    *result = *first;
    ++result; ++first;
    --n;
  }
return result;
}
//所做的事情是: 复制区间中的前N个元素到result中。

 

7.20、template <class InputIterator, class OutputIterator, class UnaryPredicate>
OutputIterator copy_if (InputIterator first, InputIterator last,
              OutputIterator result, UnaryPredicate pred)
{
  while (first!=last) {
    if (pred(*first)) { //符合条件的元素。
      *result = *first;
      ++result;
    }
    ++first;
  }
  return result;
}
//所做的事情是:复制满足pred函数中指定条件的元素。

 

7.21、template<class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2 copy_backward ( BidirectionalIterator1 first,
                       BidirectionalIterator1 last,
                       BidirectionalIterator2 result )
{
  while (last!=first) 
    *(--result) = *(--last);//转进来的result是end()。
  return result;
}
//所做的事情是:将区间从后向前的复制。

 

7.27、template <class InputIterator, class OutputIterator, class UnaryOperator>
OutputIterator transform (InputIterator first1, InputIterator last1,
               OutputIterator result, UnaryOperator op)
{
  while (first1 != last1) {
    *result = op(*first1); // or: *result=binary_op(*first1,*first2++); 这里的*result对象必须
                  //支持和op函数返回值的operator=;
    ++result; ++first1; //所有元素都要。
  }
  return result;
}
//所做的事情是:获得被op函数改变后的第一个区间的元素。然后返回。

 

7.30、template <class InputIterator, class OutputIterator, class T>
OutputIterator replace_copy (InputIterator first, InputIterator last,
                 OutputIterator result, const T& old_value, const T& new_value)
{
  while (first!=last) {
    *result = (*first==old_value)? new_value: *first; //全部是要复制, 只是在需要替换元素的时候
                                  //就替换。不改变原序列, 产生新的序列(result)
    ++first; ++result;
  }
  return result;
}
//所做的事情是:原序列是不变的,产生一个新的序列(result)。

 

7.31、template <class InputIterator, class OutputIterator, class UnaryPredicate, class T>
OutputIterator replace_copy_if (InputIterator first, InputIterator last,
                   OutputIterator result, UnaryPredicate pred,
const T& new_value)
{
  while (first!=last) {
    *result = (pred(*first))? new_value: *first; //全部要复制,只是替换掉满足pred函数中条件的元素
                              //就替换。不改变原序列, 产生新的序列(result)
    ++first; ++result;
  }
  return result;
}
//所做的事情是:原序列是不变的,产生一个新的序列(result)。

 

7.39、template <class InputIterator, class OutputIterator, class T>
OutputIterator remove_copy (InputIterator first, InputIterator last,
                OutputIterator result, const T& val)
{
  while (first!=last) {
    if (!(*first == val)) {
      *result = *first; //移除val然后copy
      ++result;
    }
    ++first;
  }
  return result;
}
//所做的事情是:copy区间中除了val元素之外的元素。

 

7.40、template <class InputIterator, class OutputIterator, class UnaryPredicate>
OutputIterator remove_copy_if (InputIterator first, InputIterator last,
                  OutputIterator result, UnaryPredicate pred)
{
  while (first!=last) {
    if (!pred(*first)) {
      *result = *first; //copy除了满足pred条件之外的元素
      ++result;
    }
    ++first;
  }
  return result;
}
//所做的事情是:copy区间中除了满足pred函数条件之外的元素。

 

7.44、template <class BidirectionalIterator, class OutputIterator>
OutputIterator reverse_copy (BidirectionalIterator first,
                 BidirectionalIterator last, 
                 OutputIterator result) {   while (first!=last) {     --last;     *result = *last;//反转后的数据copy到result中。     ++result;   }   return result; } //所做的事情是:将区间中的数据进行反转然后copy到result中。

 

变动性算法:

7.22、template<class InputIterator, class OutputIterator> //!!!!!!!!!!!!!!!!!!!!
OutputIterator move (InputIterator first, InputIterator last, OutputIterator result)
{
  while (first!=last) {
    *result = std::move(*first);
    ++result; ++first;
  }
  return result;
}

 

7.23、template<class BidirectionalIterator1, class BidirectionalIterator2> //!!!!!!!!!!!!!!!!
BidirectionalIterator2 move_backward ( BidirectionalIterator1 first,
                       BidirectionalIterator1 last,
                       BidirectionalIterator2 result )
{    
  while (last!=first) 
    *(--result) = std::move(*(--last));
  return result;
}

 

7.24、template <class T> void swap ( T& a, T& b )
{
  T c(a); //拷贝构造 
  a=b; //op=
  b=c; //op=
}
//交换两个对象。

template <class T> //!!!!!!!!!!1
void swap (T& a, T& b)
{
  T c(std::move(a)); 
  a=std::move(b); 
  b=std::move(c);
}
template <class T, size_t N> 
void swap (T (&a)[N], T (&b)[N]) //两个相同大小的对象数组。
{
  for (size_t i = 0; i<N; ++i) 
    swap (a[i],b[i]);
}

 

7.25、template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1,
                  ForwardIterator2 first2)
{
  while (first1!=last1) {
    swap (*first1, *first2); //两个元素的交换。
    ++first1; ++first2; //第二个区间一定要是和第一个区间一样或是大于的,不然就会出错。
  }
  return first2;
}
//所做的事情是:将第一个区间的元素和第二个区间的元素进行交换, 换句话是:范围交换。

 

7.26、template <class ForwardIterator1, class ForwardIterator2>
void iter_swap (ForwardIterator1 a, ForwardIterator2 b)
{
  swap (*a, *b);
}
//所做的事情是:交换的是迭代器。

 

7.28、template <class ForwardIterator, class T>
void replace (ForwardIterator first, ForwardIterator last,
const T& old_value, const T& new_value)
{
  while (first!=last) {
    if (*first == old_value) //如果是想要调换的元素 
      *first=new_value; //就调换。
    ++first;
  }
}
//所做的事情是:调换区间中想要调换的元素,old_value -> new_value;

 

7.29、template < class ForwardIterator, class UnaryPredicate, class T >
void replace_if (ForwardIterator first, ForwardIterator last,
          UnaryPredicate pred, const T& new_value)
{
  while (first!=last) {
    if (pred(*first)) //pred函数指定条件。
      *first=new_value; //替换指定条件下的元素。
    ++first;
  }
}
//所做的事情是:替换掉pred函数指定条件下的元素

 

7.32、template <class ForwardIterator, class T>
void fill (ForwardIterator first, ForwardIterator last, const T& val)
{
  while (first != last) {
    *first = val; //进行区间的填充。
    ++first;
  }
}
//所做的事情是:进行区间的填充。

 

7.33、template <class OutputIterator, class Size, class T>
OutputIterator fill_n (OutputIterator first, Size n, const T& val)
{    
  while (n>0) { //begin()之后填充 n 个 val
    *first = val; 
    ++first; --n;
  }
  return first; 
}
//所做的事情是:为区间填充n 个val。

 

7.34、template <class ForwardIterator, class Generator>
void generate ( ForwardIterator first, ForwardIterator last, Generator gen )
{
  while (first != last) {
    *first = gen(); //gen()生产数据。
    ++first;
  }
}
//所做的事情是:为区间填充gen()中生产中的元素。

 

7.35、template <class OutputIterator, class Size, class Generator>
void generate_n ( OutputIterator first, Size n, Generator gen )
{
  while (n>0) {
    *first = gen(); //填充n个。
    ++first; --n;
  }
}
//所做的事情是:为区间填充gen()中生产中的元素 n 个。

 

7.36、template <class ForwardIterator, class T>
ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val)
{
  ForwardIterator result = first;
  while (first!=last) {
    if (!(*first == val)) {
      *result = *first; //去除掉区间中的val对象。
      ++result;
    }
    ++first;
  }
  return result;
}
//所做的事情是:去除掉区间中的val对象。

//注意:在做完整个函数的时候remove也就做完了,但是result到last之间存在的是垃圾数据,所以需要自己进行
//删除。而这个函数正好返回result,以便进行垃圾数据的删除。换句话说result就是有效数据的end().
//可以使用resize()函数进行删除.因为new_size < 当前size的时候,resize()函数会直接调用pop_back()进行后面的删除。

 

7.37、template <class ForwardIterator, class T> //!!!!!!!!!!!!!!!!!!!
ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val)
{
  ForwardIterator result = first;
  while (first!=last) {
    if (!(*first == val)) {
      *result = move(*first);
      ++result; 
    }
  ++first;
  }
  return result;
}

 

7.38、template <class ForwardIterator, class UnaryPredicate>
ForwardIterator remove_if (ForwardIterator first, ForwardIterator last,
                UnaryPredicate pred)
{
  ForwardIterator result = first;
  while (first!=last) {
    if (!pred(*first)) { //符合就移除。
      *result = *first;
      ++result;
    }
  ++first;
  }
  return result;
}
//所做的事情是:选择性的移除。

 

7.41、template <class ForwardIterator>
ForwardIterator unique (ForwardIterator first, ForwardIterator last)
{
  if (first==last) return last;
  ForwardIterator result = first;
  while (++first != last)
  {
    if (!(*result == *first)) // or: if (!pred(*result,*first)) for version (2)
      *(++result) = *first; //消除掉相邻且相等的两个或多个元素,只留一个(注意只是相邻)
  }
  return ++result;
  } 
//所做的事情是:消除掉相邻且相等的两个或多个元素,只留一个(注意只是相邻)
// 1 2 2 3 3 4 2 2 2 2 5 5 6 7 -> 1 2 3 4 2 5 6 7

 

7.42、template <class InputIterator, class OutputIterator>
OutputIterator unique_copy (InputIterator first, InputIterator last,
                OutputIterator result)
{    
  if (first==last) return result;
  *result = *first;
  while (++first != last) {
    typename iterator_traits<InputIterator>::value_type val = *first;
    if (!(*result == val)) 
      *(++result) = val; //消除掉相邻且相等的两个或多个元素,然后copy到result中,
  }
  return ++result;
}
//所做的事情是:消除掉相邻且相等的两个或多个元素,然后copy到result中。

 

7.43、template <class BidirectionalIterator>
void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
  while ((first!=last)&&(first!=--last)) {
    std::iter_swap (first,last); //反转
    ++first;
  }
}
//所做的事情是:进行区间元素的反转。

 

7.45、template <class ForwardIterator>
void rotate (ForwardIterator first, ForwardIterator middle,
        ForwardIterator last)
{
  ForwardIterator next = middle;//middle是指定的位置。
  while (first!=next)
  {
    swap (*first++,*next++);
    if (next==last) next=middle;
    else if (first==middle) middle = next;
  }
}
//所做的事情是:根据所给指定的位置进行前后元素的调换。
//1 2 3 4 5 6 7 8 9 如果middle的位置为第四个位置 -> 5 6 7 8 9 1 2 3 4

 

7.46、template <class ForwardIterator, class OutputIterator>
OutputIterator rotate_copy (ForwardIterator first, ForwardIterator middle,
                ForwardIterator last, OutputIterator result)
{
  result=std::copy (middle,last,result);
  return std::copy (first,middle,result);
}
//所做的事情是: 两次copy 得到了和rotate函数一样的 数据循序, 这个数据存在result中。

 

7.47、template <class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,
            RandomNumberGenerator& gen)
{
  iterator_traits<RandomAccessIterator>::difference_type i, n;
  n = (last - first);
  for (i = n-1; i > 0; --i) {
    swap (first[i],first[gen(i+1)]);//gen()函数获得随机的区间值
  }
}
//将区间中的值按照gen函数进行位置的改变。

 

7.48、template <class RandomAccessIterator, class URNG> //!!!!!!!!!!!!!!!!!!!!!!!!
void shuffle (RandomAccessIterator first, RandomAccessIterator last, URNG&& g)
{
  for (auto i=(last-first)-1; i>0; --i) {
    std::uniform_int_distribution<decltype(i)> d(0,i);
    swap (first[i], first[d(g)]);
  }
}

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