STL-algorithm-2

Modifying sequence operations:

copy

template <class InputIterator, class OutputIterator>  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);

将范围[first,last)中的元素复制到从result开始的范围中。 该函数将迭代器返回到目标范围的末尾(指向最后一个复制的元素后面的元素)。 范围不应以结果指向范围[first,last)中的元素的方式重叠。对于这种情况,请参阅copy_backward。

template<class InputIterator, class OutputIterator>
  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
  while (first!=last) {
    *result = *first;
    ++result; ++first;
  }
  return result;
}
// copy algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::copy
#include <vector>       // std::vector

int main () {
  int myints[]={10,20,30,40,50,60,70};
  std::vector<int> myvector (7);

  std::copy ( myints, myints+7, myvector.begin() );

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}Output:
myvector contains: 10 20 30 40 50 60 70

copy_n

template <class InputIterator, class Size, class OutputIterator>  OutputIterator copy_n (InputIterator first, Size n, OutputIterator result);

将从第一个first的范围中的前n个元素复制到从result开始的范围。 该函数将迭代器返回到目标范围的末尾(指向最后一个复制的元素的末尾)。 如果n为负数,则函数不执行任何操作。 如果范围重叠,则结果所指向的范围中的一些元素可能具有未定义但有效的值。

template<class InputIterator, class Size, class OutputIterator>
  OutputIterator copy_n (InputIterator first, Size n, OutputIterator result)
{
  while (n>0) {
    *result = *first;
    ++result; ++first;
    --n;
  }
  return result;
}
// copy_n algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::copy
#include <vector>       // std::vector

int main () {
  int myints[]={10,20,30,40,50,60,70};
  std::vector<int> myvector;

  myvector.resize(7);   // allocate space for 7 elements

  std::copy_n ( myints, 7, myvector.begin() );

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}Output:
myvector contains: 10 20 30 40 50 60 70

copy_if

template <class InputIterator, class OutputIterator, class UnaryPredicate>  OutputIterator copy_if (InputIterator first, InputIterator last,                          OutputIterator result, UnaryPredicate pred);

将pred返回true的范围[first,last)中的元素复制到从结果开始的范围。

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;
}
// copy_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::copy_if, std::distance
#include <vector>       // std::vector

int main () {
  std::vector<int> foo = {25,15,5,-5,-15};
  std::vector<int> bar (foo.size());

  // copy only positive numbers:
  auto it = std::copy_if (foo.begin(), foo.end(), bar.begin(), [](int i){return !(i<0);} );
  bar.resize(std::distance(bar.begin(),it));  // shrink container to new size

  std::cout << "bar contains:";
  for (int& x: bar) std::cout << ' ' << x;
  std::cout << '\n';

  return 0;
}Output:
bar contains: 25 15 5

copy_backward

template <class BidirectionalIterator1, class BidirectionalIterator2>  BidirectionalIterator2 copy_backward (BidirectionalIterator1 first,                                        BidirectionalIterator1 last,                                        BidirectionalIterator2 result);

将范围[first,last)中从末尾开始的元素复制到以result结束的范围中。

函数将迭代器返回到目标范围中的第一个元素。

生成的范围中的元素的顺序与[first,last)完全相同。要反转它们的顺序,请参阅reverse_copy。

该函数首先将*(last-1)复制到*(result-1)中,然后向后跟随这些元素之前的元素,直到到达first元素(并包括它)。

范围不应以这样的方式重叠,即结果(即目标范围中的结束元素)指向范围(first,last)中的元素。对于这种情况,请参阅副本。

template<class BidirectionalIterator1, class BidirectionalIterator2>
  BidirectionalIterator2 copy_backward ( BidirectionalIterator1 first,
                                         BidirectionalIterator1 last,
                                         BidirectionalIterator2 result )
{
  while (last!=first) *(--result) = *(--last);
  return result;
}
// copy_backward example
#include <iostream>     // std::cout
#include <algorithm>    // std::copy_backward
#include <vector>       // std::vector

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

  // set some values:
  for (int i=1; i<=5; i++)
    myvector.push_back(i*10);          // myvector: 10 20 30 40 50

  myvector.resize(myvector.size()+3);  // allocate space for 3 more elements

  std::copy_backward ( myvector.begin(), myvector.begin()+5, myvector.end() );

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
myvector contains: 10 20 30 10 20 30 40 50

move

template <class InputIterator, class OutputIterator>  OutputIterator move (InputIterator first, InputIterator last, OutputIterator result);

将范围[first,last)中的元素移动到从结果开始的范围中。

[first,last)中的元素的值被转移到result所指向的元素。调用后,[first、last)范围中的元素将处于未指定但有效的状态。

范围不应以结果指向范围[first,last)中的元素的方式重叠。对于这种情况,请参阅move_backward。

template<class InputIterator, class OutputIterator>
  OutputIterator move (InputIterator first, InputIterator last, OutputIterator result)
{
  while (first!=last) {
    *result = std::move(*first);
    ++result; ++first;
  }
  return result;
}
// move algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::move (ranges)
#include <utility>      // std::move (objects)
#include <vector>       // std::vector
#include <string>       // std::string

int main () {
  std::vector<std::string> foo = {"air","water","fire","earth"};
  std::vector<std::string> bar (4);

  // moving ranges:
  std::cout << "Moving ranges...\n";
  std::move ( foo.begin(), foo.begin()+4, bar.begin() );

  std::cout << "foo contains " << foo.size() << " elements:";
  std::cout << " (each in an unspecified but valid state)";
  std::cout << '\n';

  std::cout << "bar contains " << bar.size() << " elements:";
  for (std::string& x: bar) std::cout << " [" << x << "]";
  std::cout << '\n';

  // moving container:
  std::cout << "Moving container...\n";
  foo = std::move (bar);

  std::cout << "foo contains " << foo.size() << " elements:";
  for (std::string& x: foo) std::cout << " [" << x << "]";
  std::cout << '\n';

  std::cout << "bar is in an unspecified but valid state";
  std::cout << '\n';

  return 0;
}Possible output:
Moving ranges...
foo contains 4 elements: (each in an unspecified but valid state)
bar contains 4 elements: [air] [water] [fire] [earth]
Moving container...
foo contains 4 elements: [air] [water] [fire] [earth]
bar is in an unspecified but valid state

move_backward

template <class BidirectionalIterator1, class BidirectionalIterator2>  BidirectionalIterator2 move_backward (BidirectionalIterator1 first,                                        BidirectionalIterator1 last,                                        BidirectionalIterator2 result);

将范围[first,last) 中的元素从末尾开始移动到以result结束的范围。

函数将迭代器返回到目标范围中的第一个元素。

生成的范围中的元素的顺序与[first,last)完全相同。要反转它们的顺序,请参见反转。

函数从将*(last-1)移动到*(result-1)开始,然后向后移动这些元素之前的元素,直到到达第一个元素(并包括它)。

范围不应以这样的方式重叠,即result(即目标范围中的结束元素)指向范围(first,last]中的元素。对于这种情况,请参阅move。

template<class BidirectionalIterator1, class BidirectionalIterator2>
  BidirectionalIterator2 move_backward ( BidirectionalIterator1 first,
                                         BidirectionalIterator1 last,
                                         BidirectionalIterator2 result )
{
  while (last!=first) *(--result) = std::move(*(--last));
  return result;
}
// move_backward example
#include <iostream>     // std::cout
#include <algorithm>    // std::move_backward
#include <string>       // std::string

int main () {
  std::string elems[10] = {"air","water","fire","earth"};

  // insert new element at the beginning:
  std::move_backward (elems,elems+4,elems+5);
  elems[0]="ether";

  std::cout << "elems contains:";
  for (int i=0; i<10; ++i)
    std::cout << " [" << elems[i] << "]";
  std::cout << '\n';

  return 0;
}Output:
elems contains: [ether] [air] [water] [fire] [earth] [] [] [] [] []

swap

header
// moved from <algorithm> to <utility> in C++11
non-array (1)
template <class T> void swap (T& a, T& b)  noexcept (is_nothrow_move_constructible<T>::value && is_nothrow_move_assignable<T>::value);
array (2)
template <class T, size_t N> void swap(T (&a)[N], T (&b)[N])  noexcept (noexcept(swap(*a,*b)));

交换a和b的值。

template <class T> 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]);
}
// swap algorithm example (C++98)
#include <iostream>     // std::cout
#include <algorithm>    // std::swap
#include <vector>       // std::vector

int main () {

  int x=10, y=20;                              // x:10 y:20
  std::swap(x,y);                              // x:20 y:10

  std::vector<int> foo (4,x), bar (6,y);       // foo:4x20 bar:6x10
  std::swap(foo,bar);                          // foo:6x10 bar:4x20

  std::cout << "foo contains:";
  for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
foo contains: 10 10 10 10 10 10

swap_ranges

将范围[first1,last1)中的每个元素的值与从first2开始的范围中的相应元素的值进行交换。

函数调用swap(非限定)来交换元素。

template<class ForwardIterator1, class ForwardIterator2>
  ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1,
                                ForwardIterator2 first2)
{
  while (first1!=last1) {
    swap (*first1, *first2);
    ++first1; ++first2;
  }
  return first2;
}
// swap_ranges example
#include <iostream>     // std::cout
#include <algorithm>    // std::swap_ranges
#include <vector>       // std::vector

int main () {
  std::vector<int> foo (5,10);        // foo: 10 10 10 10 10
  std::vector<int> bar (5,33);        // bar: 33 33 33 33 33

  std::swap_ranges(foo.begin()+1, foo.end()-1, bar.begin());

  // print out results of swap:
  std::cout << "foo contains:";
  for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  std::cout << "bar contains:";
  for (std::vector<int>::iterator it=bar.begin(); it!=bar.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
foo contains: 10 33 33 33 10
bar contains: 10 10 10 33 33

iter_swap

template <class ForwardIterator1, class ForwardIterator2>  void iter_swap (ForwardIterator1 a, ForwardIterator2 b);

交换由a和b指向的元素。 函数调用swap(非限定)来交换元素。

template <class ForwardIterator1, class ForwardIterator2>
  void iter_swap (ForwardIterator1 a, ForwardIterator2 b)
{
  swap (*a, *b);
}
template <class ForwardIterator1, class ForwardIterator2>
  void iter_swap (ForwardIterator1 a, ForwardIterator2 b)
{
  swap (*a, *b);
}
// iter_swap example
#include <iostream>     // std::cout
#include <algorithm>    // std::iter_swap
#include <vector>       // std::vector

int main () {

  int myints[]={10,20,30,40,50 };              //   myints:  10  20  30  40  50
  std::vector<int> myvector (4,99);            // myvector:  99  99  99  99

  std::iter_swap(myints,myvector.begin());     //   myints: [99] 20  30  40  50
                                               // myvector: [10] 99  99  99

  std::iter_swap(myints+3,myvector.begin()+2); //   myints:  99  20  30 [99] 50
                                               // myvector:  10  99 [40] 99

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
myvector contains: 10 99 40 99

transform

unary operation(1)
template <class InputIterator, class OutputIterator, class UnaryOperation>  OutputIterator transform (InputIterator first1, InputIterator last1,                            OutputIterator result, UnaryOperation op);
binary operation(2)
template <class InputIterator1, class InputIterator2,          class OutputIterator, class BinaryOperation>  OutputIterator transform (InputIterator1 first1, InputIterator1 last1,                            InputIterator2 first2, OutputIterator result,                            BinaryOperation binary_op);

将运算顺序应用于一(1)或两(2)个范围的元素,并将结果存储在从结果开始的范围中。

(1) 一元运算 将op应用于范围[first1,last1)中的每个元素,并将每个操作返回的值存储在从结果开始的范围中。

(2) 二进制运算 调用binary_op,使用范围[first1,last1)中的每个元素作为第一个参数,并使用从first2开始的范围中的相应参数作为第二个参数。每次调用返回的值存储在从result开始的范围内。

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; ++first1;
  }
  return result;
}
// transform algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::transform
#include <vector>       // std::vector
#include <functional>   // std::plus

int op_increase (int i) { return ++i; }

int main () {
  std::vector<int> foo;
  std::vector<int> bar;

  // set some values:
  for (int i=1; i<6; i++)
    foo.push_back (i*10);                         // foo: 10 20 30 40 50

  bar.resize(foo.size());                         // allocate space

  std::transform (foo.begin(), foo.end(), bar.begin(), op_increase);
                                                  // bar: 11 21 31 41 51

  // std::plus adds together its two arguments:
  std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), std::plus<int>());
                                                  // foo: 21 41 61 81 101

  std::cout << "foo contains:";
  for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
foo contains: 21 41 61 81 101

replace

template <class ForwardIterator, class T>  void replace (ForwardIterator first, ForwardIterator last,                const T& old_value, const T& new_value);

将new_value分配给范围[first,last)中与old_value相比较的所有元素。

函数使用运算符==将各个元素与old_value进行比较。

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

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

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

  std::replace (myvector.begin(), myvector.end(), 20, 99); // 10 99 30 30 99 10 10 99

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

Output:

myvector contains: 10 99 30 30 99 10 10 99

replace_if

template <class ForwardIterator, class UnaryPredicate, class T>  void replace_if (ForwardIterator first, ForwardIterator last,                   UnaryPredicate pred, const T& new_value );

将new_value分配给pred返回true的范围[first,last)中的所有元素。

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)) *first=new_value;
    ++first;
  }
}
// replace_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::replace_if
#include <vector>       // std::vector

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

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

  // set some values:
  for (int i=1; i<10; i++) myvector.push_back(i);               // 1 2 3 4 5 6 7 8 9

  std::replace_if (myvector.begin(), myvector.end(), IsOdd, 0); // 0 2 0 4 0 6 0 8 0

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
myvector contains: 0 2 0 4 0 6 0 8 0

replace_copy

template <class InputIterator, class OutputIterator, class T>  OutputIterator replace_copy (InputIterator first, InputIterator last,                               OutputIterator result,                               const T& old_value, const T& new_value);

将范围[first,last)中的元素复制到从result开始的范围,用new_value替换old_value的外观。

函数使用运算符==将各个元素与old_value进行比较。

范围不应以这样的方式重叠,即结果指向范围[first,last)中的元素。

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;
    ++first; ++result;
  }
  return result;
}
// replace_copy example
#include <iostream>     // std::cout
#include <algorithm>    // std::replace_copy
#include <vector>       // std::vector

int main () {
  int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };

  std::vector<int> myvector (8);
  std::replace_copy (myints, myints+8, myvector.begin(), 20, 99);

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}
Output:
myvector contains: 10 99 30 30 99 10 10 99

 replace_copy_if

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);

将范围[first,last)中的元素复制到从result开始的范围,将pred返回true的元素替换为new_value。

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;
    ++first; ++result;
  }
  return result;
}
// replace_copy_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::replace_copy_if
#include <vector>       // std::vector

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

int main () {
  std::vector<int> foo,bar;

  // set some values:
  for (int i=1; i<10; i++) foo.push_back(i);          // 1 2 3 4 5 6 7 8 9

  bar.resize(foo.size());   // allocate space
  std::replace_copy_if (foo.begin(), foo.end(), bar.begin(), IsOdd, 0);
                                                        // 0 2 0 4 0 6 0 8 0

  std::cout << "bar contains:";
  for (std::vector<int>::iterator it=bar.begin(); it!=bar.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
second contains: 0 2 0 4 0 6 0 8 0

fill

template <class ForwardIterator, class T>  void fill (ForwardIterator first, ForwardIterator last, const T& val);

将val指定给范围[first,last)中的所有元素。

template <class ForwardIterator, class T>
  void fill (ForwardIterator first, ForwardIterator last, const T& val)
{
  while (first != last) {
    *first = val;
    ++first;
  }
}
// fill algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::fill
#include <vector>       // std::vector

int main () {
  std::vector<int> myvector (8);                       // myvector: 0 0 0 0 0 0 0 0

  std::fill (myvector.begin(),myvector.begin()+4,5);   // myvector: 5 5 5 5 0 0 0 0
  std::fill (myvector.begin()+3,myvector.end()-2,8);   // myvector: 5 5 5 8 8 8 0 0

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
myvector contains: 5 5 5 8 8 8 0 0

fill_n

template <class OutputIterator, class Size, class T>  OutputIterator fill_n (OutputIterator first, Size n, const T& val);

将val指定给first所指向的序列的前n个元素。

template <class OutputIterator, class Size, class T>
  OutputIterator fill_n (OutputIterator first, Size n, const T& val)
{
  while (n>0) {
    *first = val;
    ++first; --n;
  }
  return first;     // since C++11
}
// fill_n example
#include <iostream>     // std::cout
#include <algorithm>    // std::fill_n
#include <vector>       // std::vector

int main () {
  std::vector<int> myvector (8,10);        // myvector: 10 10 10 10 10 10 10 10

  std::fill_n (myvector.begin(),4,20);     // myvector: 20 20 20 20 10 10 10 10
  std::fill_n (myvector.begin()+3,3,33);   // myvector: 20 20 20 33 33 33 10 10

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}
Output:
myvector contains: 20 20 20 33 33 33 10 10

generate

template <class ForwardIterator, class Generator>  void generate (ForwardIterator first, ForwardIterator last, Generator gen);

将连续调用gen返回的值分配给范围 [first,last)中的元素。

template <class ForwardIterator, class Generator>
  void generate ( ForwardIterator first, ForwardIterator last, Generator gen )
{
  while (first != last) {
    *first = gen();
    ++first;
  }
}
// generate algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::generate
#include <vector>       // std::vector
#include <ctime>        // std::time
#include <cstdlib>      // std::rand, std::srand

// function generator:
int RandomNumber () { return (std::rand()%100); }

// class generator:
struct c_unique {
  int current;
  c_unique() {current=0;}
  int operator()() {return ++current;}
} UniqueNumber;

int main () {
  std::srand ( unsigned ( std::time(0) ) );

  std::vector<int> myvector (8);

  std::generate (myvector.begin(), myvector.end(), RandomNumber);

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  std::generate (myvector.begin(), myvector.end(), UniqueNumber);

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';
 
  return 0;
}A possible output:
myvector contains: 57 87 76 66 85 54 17 15
myvector contains: 1 2 3 4 5 6 7 8

generate_n

template <class OutputIterator, class Size, class Generator>  OutputIterator generate_n (OutputIterator first, Size n, Generator gen);

将连续调用gen返回的值分配给first指向的序列的前n个元素。

template <class OutputIterator, class Size, class Generator>
  void generate_n ( OutputIterator first, Size n, Generator gen )
{
  while (n>0) {
    *first = gen();
    ++first; --n;
  }
}
/ generate_n example
#include <iostream>     // std::cout
#include <algorithm>    // std::generate_n

int current = 0;
int UniqueNumber () { return ++current; }

int main () {
  int myarray[9];

  std::generate_n (myarray, 9, UniqueNumber);

  std::cout << "myarray contains:";
  for (int i=0; i<9; ++i)
    std::cout << ' ' << myarray[i];
  std::cout << '\n';

  return 0;
}A possible output:
myarray contains: 1 2 3 4 5 6 7 8 9

remove

template <class ForwardIterator, class T>  ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val);

[注意:这是算法remove的参考。请参阅remove了解<cstdio>的remove。]

将范围[first,last)转换为删除了所有与val相比较的元素的范围,并向该范围的新末尾返回迭代器。

函数不能改变包含元素范围的对象的属性(即,它不能改变数组或容器的大小):删除是通过将与val相等的元素替换为下一个不相等的元素来完成的,以及通过将迭代器返回到应该被认为是其新的超过结束元素的元素来用信号通知缩短范围的新大小。

未删除的元素的相对顺序被保留,而返回的迭代器和最后一个迭代器之间的元素则处于有效但未指定的状态。

函数使用运算符==将各个元素与值进行比较。

template <class ForwardIterator, class T>
  ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val)
{
  ForwardIterator result = first;
  while (first!=last) {
    if (!(*first == val)) {
      if (result!=first)
        *result = move(*first);
      ++result;
    }
    ++first;
  }
  return result;
}
// remove algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::remove

int main () {
  int myints[] = {10,20,30,30,20,10,10,20};      // 10 20 30 30 20 10 10 20

  // bounds of range:
  int* pbegin = myints;                          // ^
  int* pend = myints+sizeof(myints)/sizeof(int); // ^                       ^

  pend = std::remove (pbegin, pend, 20);         // 10 30 30 10 10 ?  ?  ?
                                                 // ^              ^
  std::cout << "range contains:";
  for (int* p=pbegin; p!=pend; ++p)
    std::cout << ' ' << *p;
  std::cout << '\n';

  return 0;
}
Output:
range contains: 10 30 30 10 10

remove_if

template <class ForwardIterator, class UnaryPredicate>  ForwardIterator remove_if (ForwardIterator first, ForwardIterator last,                             UnaryPredicate pred);

将范围[first,last)转换为删除了pred返回true的所有元素的范围,并将迭代器返回到该范围的新末尾。

函数不能改变包含元素范围的对象的属性(即,它不能改变数组或容器的大小):删除是通过将pred返回true的元素替换为下一个不返回true的元件来完成的,以及通过将迭代器返回到应该被认为是其新的超过结束元素的元素来用信号通知缩短范围的新大小。

未删除的元素的相对顺序被保留,而返回的迭代器和最后一个迭代器之间的元素则处于有效但未指定的状态。

template <class ForwardIterator, class UnaryPredicate>
  ForwardIterator remove_if (ForwardIterator first, ForwardIterator last,
                             UnaryPredicate pred)
{
  ForwardIterator result = first;
  while (first!=last) {
    if (!pred(*first)) {
      if (result!=first)
        *result = std::move(*first);
      ++result;
    }
    ++first;
  }
  return result;
}
// remove_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::remove_if

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

int main () {
  int myints[] = {1,2,3,4,5,6,7,8,9};            // 1 2 3 4 5 6 7 8 9

  // bounds of range:
  int* pbegin = myints;                          // ^
  int* pend = myints+sizeof(myints)/sizeof(int); // ^                 ^

  pend = std::remove_if (pbegin, pend, IsOdd);   // 2 4 6 8 ? ? ? ? ?
                                                 // ^       ^
  std::cout << "the range contains:";
  for (int* p=pbegin; p!=pend; ++p)
    std::cout << ' ' << *p;
  std::cout << '\n';

  return 0;
}Output:
the range contains: 2 4 6 8

remove_copy

template <class InputIterator, class OutputIterator, class T>  OutputIterator remove_copy (InputIterator first, InputIterator last,                              OutputIterator result, const T& val);

将范围[first,last)中的元素复制到从result开始的范围,但比较等于val的元素除外。

结果范围比[first,last)短了序列中匹配的元素数量,这些元素被“删除”。

函数使用运算符==将各个元素与值进行比较。

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;
      ++result;
    }
    ++first;
  }
  return result;
}
// remove_copy example
#include <iostream>     // std::cout
#include <algorithm>    // std::remove_copy
#include <vector>       // std::vector

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

  std::remove_copy (myints,myints+8,myvector.begin(),20); // 10 30 30 10 10 0 0 0

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}
Output:
myvector contains: 10 30 30 10 10 0 0 0

remove_copy_if

template <class InputIterator, class OutputIterator, class UnaryPredicate>  OutputIterator remove_copy_if (InputIterator first, InputIterator last,                                 OutputIterator result, UnaryPredicate pred);

将范围[first,last) 中的元素复制到从result开始的范围,pred返回true的元素除外。

结果范围比[first,last) 短的元素数量与匹配的元素数量一样多,这些元素被“删除”。

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;
      ++result;
    }
    ++first;
  }
  return result;
}
// remove_copy_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::remove_copy_if
#include <vector>       // std::vector

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

int main () {
  int myints[] = {1,2,3,4,5,6,7,8,9};
  std::vector<int> myvector (9);

  std::remove_copy_if (myints,myints+9,myvector.begin(),IsOdd);

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
myvector contains: 2 4 6 8 0 0 0 0 0

unique

equality (1)

template <class ForwardIterator>  ForwardIterator unique (ForwardIterator first, ForwardIterator last);

predicate (2)

template <class ForwardIterator, class BinaryPredicate>  ForwardIterator unique (ForwardIterator first, ForwardIterator last,                          BinaryPredicate pred);

从范围[first,last)中的每个连续等效元素组中删除除第一个元素外的所有元素。

函数不能改变包含元素范围的对象的属性(即,它不能改变数组或容器的大小):删除是通过用下一个不是重复的元素替换重复的元素来完成的,并通过向应该被视为新的结束元素的元素返回迭代器来通知缩短范围的新大小。

未删除的元素的相对顺序被保留,而返回的迭代器和last迭代器之间的元素则处于有效但未指定的状态。

函数使用运算符==来比较元素对(或版本(2)中的pred)。

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;
}
// unique algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::unique, std::distance
#include <vector>       // std::vector

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

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

  // using default comparison:
  std::vector<int>::iterator it;
  it = std::unique (myvector.begin(), myvector.end());   // 10 20 30 20 10 ?  ?  ?  ?
                                                         //                ^

  myvector.resize( std::distance(myvector.begin(),it) ); // 10 20 30 20 10

  // using predicate comparison:
  std::unique (myvector.begin(), myvector.end(), myfunction);   // (no changes)

  // print out content:
  std::cout << "myvector contains:";
  for (it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
myvector contains: 10 20 30 20 10

unique_copy

equality (1)
template <class InputIterator, class OutputIterator>  OutputIterator unique_copy (InputIterator first, InputIterator last,                              OutputIterator result);
predicate (2)
template <class InputIterator, class OutputIterator, class BinaryPredicate>  OutputIterator unique_copy (InputIterator first, InputIterator last,                              OutputIterator result, BinaryPredicate pred);

将范围[first,last)中的元素复制到从result开始的范围,但连续重复的元素(与前面的元素相比相等的元素)除外。

仅复制范围[first,last)中每个连续等效元素组中的第一个元素。

元素之间的比较是通过在它们之间应用运算符==或模板参数pred(对于第二个版本)来执行的。

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))   // or: if (!pred(*result,val)) for version (2)
      *(++result)=val;
  }
  return ++result;
}
// unique_copy example
#include <iostream>     // std::cout
#include <algorithm>    // std::unique_copy, std::sort, std::distance
#include <vector>       // std::vector

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

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

  // using default comparison:
  std::vector<int>::iterator it;
  it=std::unique_copy (myints,myints+9,myvector.begin());   // 10 20 30 20 10 0  0  0  0
                                                            //                ^

  std::sort (myvector.begin(),it);                          // 10 10 20 20 30 0  0  0  0
                                                            //                ^

  // using predicate comparison:
  it=std::unique_copy (myvector.begin(), it, myvector.begin(), myfunction);
                                                            // 10 20 30 20 30 0  0  0  0
                                                            //          ^

  myvector.resize( std::distance(myvector.begin(),it) );    // 10 20 30

  // print out content:
  std::cout << "myvector contains:";
  for (it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}
Output:
myvector contains: 10 20 30

reverse

template <class BidirectionalIterator>  void reverse (BidirectionalIterator first, BidirectionalIterator last);

反转范围[first,last)中元素的顺序。

该函数调用iter_swap将元素交换到它们的新位置。

template <class BidirectionalIterator>
  void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
  while ((first!=last)&&(first!=--last)) {
    std::iter_swap (first,last);
    ++first;
  }
}
// reverse algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::reverse
#include <vector>       // std::vector

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

  // set some values:
  for (int i=1; i<10; ++i) myvector.push_back(i);   // 1 2 3 4 5 6 7 8 9

  std::reverse(myvector.begin(),myvector.end());    // 9 8 7 6 5 4 3 2 1

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}
Output:
myvector contains: 9 8 7 6 5 4 3 2 1

reverse_copy

template <class BidirectionalIterator, class OutputIterator>  OutputIterator reverse_copy (BidirectionalIterator first,                               BidirectionalIterator last, OutputIterator result);

将范围 [first,last) 中的元素复制到从result开始的范围,但顺序相反。

template <class BidirectionalIterator, class OutputIterator>
  OutputIterator reverse_copy (BidirectionalIterator first,
                               BidirectionalIterator last, OutputIterator result)
{
  while (first!=last) {
    --last;
    *result = *last;
    ++result;
  }
  return result;
}
// reverse_copy example
#include <iostream>     // std::cout
#include <algorithm>    // std::reverse_copy
#include <vector>       // std::vector

int main () {
  int myints[] ={1,2,3,4,5,6,7,8,9};
  std::vector<int> myvector;

  myvector.resize(9);    // allocate space

  std::reverse_copy (myints, myints+9, myvector.begin());

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}Output:
myvector contains: 9 8 7 6 5 4 3 2 1

rotate

template <class ForwardIterator>  ForwardIterator rotate (ForwardIterator first, ForwardIterator middle,                          ForwardIterator last);

旋转范围[first,last)中元素的顺序,使middle指向的元素成为新的第一个元素。

template <class ForwardIterator>
  void rotate (ForwardIterator first, ForwardIterator middle,
               ForwardIterator last)
{
  ForwardIterator next = middle;
  while (first!=next)
  {
    swap (*first++,*next++);
    if (next==last) next=middle;
    else if (first==middle) middle=next;
  }
}
// rotate algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::rotate
#include <vector>       // std::vector

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

  // set some values:
  for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

  std::rotate(myvector.begin(),myvector.begin()+3,myvector.end());
                                                  // 4 5 6 7 8 9 1 2 3
  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}
Output:
myvector contains: 4 5 6 7 8 9 1 2 3

rotate_copy

template <class ForwardIterator, class OutputIterator>  OutputIterator rotate_copy (ForwardIterator first, ForwardIterator middle,                              ForwardIterator last, OutputIterator result);

将范围[first,last)中的元素复制到从result开始的范围,但旋转元素的顺序,使middle指向的元素成为结果范围中的first元素。

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);
}
// rotate_copy algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::rotate_copy
#include <vector>       // std::vector

int main () {
  int myints[] = {10,20,30,40,50,60,70};

  std::vector<int> myvector (7);

  std::rotate_copy(myints,myints+3,myints+7,myvector.begin());

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
myvector contains: 40 50 60 70 10 20 30

random_shuffle

generator by default (1)
template <class RandomAccessIterator>  void random_shuffle (RandomAccessIterator first, RandomAccessIterator last);
specific generator (2)
template <class RandomAccessIterator, class RandomNumberGenerator>  void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,                       RandomNumberGenerator&& gen);

随机重新排列范围中的元素[first,last)。

该函数将每个元素的值与其他一些随机拾取的元素的值进行交换。当提供时,函数gen确定在每种情况下拾取哪个元素。否则,函数会使用一些未指定的随机性来源。

要将统一随机生成器指定为<random>中定义的生成器,请参见shuffle。

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)]);
  }
}
// random_shuffle example
#include <iostream>     // std::cout
#include <algorithm>    // std::random_shuffle
#include <vector>       // std::vector
#include <ctime>        // std::time
#include <cstdlib>      // std::rand, std::srand

// random generator function:
int myrandom (int i) { return std::rand()%i;}

int main () {
  std::srand ( unsigned ( std::time(0) ) );
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

  // using built-in random generator:
  std::random_shuffle ( myvector.begin(), myvector.end() );

  // using myrandom:
  std::random_shuffle ( myvector.begin(), myvector.end(), myrandom);

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}Possible output:
myvector contains: 3 4 1 6 8 9 2 7 5

shuffle

template <class RandomAccessIterator, class URNG>  void shuffle (RandomAccessIterator first, RandomAccessIterator last, URNG&& g);

使用g作为均匀随机数生成器,随机重新排列范围[first,last) 中的元素。

该函数将每个元素的值与其他一些随机拾取的元素的值进行交换。函数确定通过调用g()拾取的元素。

此函数适用于<random>中定义的标准生成器。要在没有这样的生成器的情况下打乱范围中的元素,请参阅random_shuffle。

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)]);
  }
}
// shuffle algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::shuffle
#include <array>        // std::array
#include <random>       // std::default_random_engine
#include <chrono>       // std::chrono::system_clock

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

  // obtain a time-based seed:
  unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();

  shuffle (foo.begin(), foo.end(), std::default_random_engine(seed));

  std::cout << "shuffled elements:";
  for (int& x: foo) std::cout << ' ' << x;
  std::cout << '\n';

  return 0;
}Possible output:
shuffled elements: 3 1 4 2 5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值