STL中算法锦集(三)

STL中算法锦集(三)

文章目录

  • STL中算法锦集(三)
    • 一、< algorithm >
      • 1.std::find_if
      • 2.std::find_if_not
      • 3.std::for_each
      • 4.std::generate
      • 5.std::generate_n
      • 6.std::includes
      • 7.std::inplace_merge
      • 8.std::is_heap
      • 9.std::is_heap_until
      • 10.std::is_partitioned

一、< algorithm >

1.std::find_if

  • 原型:
template <class InputIterator, class UnaryPredicate>
   InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred);
  • 参数:
  • InputIterator first:区间的开始
  • InputIterator last:区间的结束
  • UnaryPredicate pred:自定义比较规则,可以是函数指针或者仿函数对象、lambda表达式
  • 作用:[first,last)区间内找满足pred条件的元素
  • 返回值:返回第一个满足pred条件的位置
  • 实现:
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      // std::cout
#include     // std::find_if
#include        // 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

2.std::find_if_not

  • 原型:
template <class InputIterator, class UnaryPredicate>
   InputIterator find_if_not (InputIterator first, InputIterator last, UnaryPredicate pred);
  • 参数:
  • InputIterator first:区间的开始
  • InputIterator last:区间的结束
  • UnaryPredicate pred:自定义比较规则,可以是函数指针或者仿函数对象、lambda表达式
  • 作用:[first,last)区间找满足第一个不满足pred条件元素的位置
  • 返回值:返回第一个不满足pred条件元素的位置
  • 实现:
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      // std::cout
#include     // std::find_if_not
#include         // 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

3.std::for_each

  • 原型:
template <class InputIterator, class Function>
   Function for_each (InputIterator first, InputIterator last, Function fn);
  • 参数:
  • InputIterator first:区间的开始
  • InputIterator last:区间的结束
  • Function fn:自定义动作,可以是函数指针或者仿函数对象、lambda表达式
  • 作用:对[first,last)区间内的每个元素执行fn
  • 返回值:返回每个元素执行的函数fn
  • 实现:
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      // std::cout
#include     // std::for_each
#include        // 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

4.std::generate

  • 原型:
template <class ForwardIterator, class Generator>
  void generate (ForwardIterator first, ForwardIterator last, Generator gen);
  • 参数:
  • ForwardIterator first:区间的开始
  • ForwardIterator last:区间的结束
  • Generator gen:自定义函数,可以是函数指针或者仿函数对象、lambda表达式
  • 作用:把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      // std::cout
#include     // std::generate
#include        // std::vector
#include         // std::time
#include       // 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

5.std::generate_n

  • 原型:
//98
template <class OutputIterator, class Size, class Generator>
  void generate_n (OutputIterator first, Size n, Generator gen);

//11
template <class OutputIterator, class Size, class Generator>
  OutputIterator generate_n (OutputIterator first, Size n, Generator gen);
  • 参数:
  • OutputIterator first:区间的开始
  • Size n:个数
  • Generator gen:自定义函数
  • 作用:把gen函数的返回值作为[first,last)区间前n个元素的值
  • 返回值:11返回最后一个成功赋值位置的下一个位置
  • 实现:
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      // std::cout
#include     // 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

6.std::includes

  • 原型:
template <class InputIterator1, class InputIterator2>
  bool includes ( InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2, InputIterator2 last2 );

template <class InputIterator1, class InputIterator2, class Compare>
  bool includes ( InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2, InputIterator2 last2, Compare comp );
  • 参数:
  • InputIterator1 first1:区间的开始
  • InputIterator1 last1:区间的结束
  • InputIterator2 first2:区间的开始
  • InputIterator2 last2:区间的结束
  • Compare comp:自定义比较规则
  • 需要排序
  • 作用:[first1,last1)区间是否全部包含[first2,last2)中的所有元素
  • 返回值:是则返回true,反之返回false
  • 实现:
template <class InputIterator1, class InputIterator2>
  bool includes (InputIterator1 first1, InputIterator1 last1,
                 InputIterator2 first2, InputIterator2 last2)
{
  while (first2!=last2) {
    if ( (first1==last1) || (*first2 < *first1) ) return false;
    if (!(*first1 < *first2)) ++first2;
    ++first1;
  }
  return true;
}
  • 案例:
// includes algorithm example
#include      // std::cout
#include     // std::includes, std::sort

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

int main () {
  int container[] = {5,10,15,20,25,30,35,40,45,50};
  int continent[] = {40,30,20,10};

  std::sort (container,container+10);
  std::sort (continent,continent+4);

  // using default comparison:
  if ( std::includes(container,container+10,continent,continent+4) )
    std::cout << "container includes continent!\n";

  // using myfunction as comp:
  if ( std::includes(container,container+10,continent,continent+4, myfunction) )
    std::cout << "container includes continent!\n";

  return 0;
}

Output:
container includes continent!
container includes continent!

7.std::inplace_merge

  • 原型:
template <class BidirectionalIterator>
  void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle,
                      BidirectionalIterator last);
                      	
template <class BidirectionalIterator, class Compare>
  void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle,
                      BidirectionalIterator last, Compare comp);
  • 参数:
  • BidirectionalIterator first:区间的开始
  • BidirectionalIterator middle:区间的中间位置,即分割线
  • BidirectionalIterator last:区间的结束
  • Compare comp:自定义比较规则
  • [first,middle)区间和[middle,last)区间都需要有序,功能类似与排序,只不过是两个有序小区间合并成一个大的有序区间
  • 作用:把[first,middle)区间和[middle,last)区间合并并排序
  • 返回值:无返回值
  • 案例:
// inplace_merge example
#include      // std::cout
#include     // std::inplace_merge, std::sort, std::copy
#include        // std::vector

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  std::vector<int> v(10);
  std::vector<int>::iterator it;

  //5 10 15 20 25
  std::sort (first,first+5);
  //10 20 30 40 50
  std::sort (second,second+5);

  //5 10 15 20 25 : 10 20 30 40 50
  it=std::copy (first, first+5, v.begin());
     std::copy (second,second+5,it);

  std::inplace_merge (v.begin(),v.begin()+5,v.end());

  std::cout << "The resulting vector contains:";
  for (it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

Output:
The resulting vector contains: 5 10 10 15 20 20 25 30 40 50

8.std::is_heap

  • 原型:
template <class RandomAccessIterator>
  bool is_heap (RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class Compare>
  bool is_heap (RandomAccessIterator first, RandomAccessIterator last,
                Compare comp);
  • 参数:
  • RandomAccessIterator first:区间的开始
  • RandomAccessIterator last:区间的结束
  • Compare comp:自定义比较规则,可以是函数指针或者仿函数对象、lambda表达式
  • 作用:判断[first,last)区间元素是否构成一个堆
  • 返回值:true代表构成一个堆,反之不构成堆
  • 案例:
// is_heap example
#include      // std::cout
#include     // std::is_heap, std::make_heap, std::pop_heap
#include        // std::vector

int main () {
  std::vector<int> foo {9,5,2,6,4,1,3,8,7};

  if (!std::is_heap(foo.begin(),foo.end()))
    std::make_heap(foo.begin(),foo.end());

  std::cout << "Popping out elements:";
  while (!foo.empty()) {
    std::pop_heap(foo.begin(),foo.end());   // moves largest element to back
    std::cout << ' ' << foo.back();         // prints back
    foo.pop_back();                         // pops element out of container
  }
  std::cout << '\n';

  return 0;
}

Output:
Popping out elements: 9 8 7 6 5 4 3 2 1

9.std::is_heap_until

  • 原型:
template <class RandomAccessIterator>
  RandomAccessIterator is_heap_until (RandomAccessIterator first,
                                      RandomAccessIterator last);

template <class RandomAccessIterator, class Compare>
  RandomAccessIterator is_heap_until (RandomAccessIterator first,
                                      RandomAccessIterator last
                                      Compare comp);
  • 参数:
  • RandomAccessIterator first:区间的开始
  • RandomAccessIterator last:区间的结束
  • Compare comp:自定义比较规则,可以是函数指针或者仿函数对象、lambda表达式
  • 作用:求[first,last)区间内第一个导致不满足堆特性的元素位置
  • 返回值:返回第一个导致不满足堆特性的元素位置
  • 案例:
#include      // std::cout
#include     // std::is_heap_until, std::sort, std::reverse
#include        // std::vector

int main () {
  std::vector<int> foo {2,6,9,3,8,4,5,1,7};

  std::sort(foo.begin(),foo.end());
  std::reverse(foo.begin(),foo.end());

  auto last = std::is_heap_until (foo.begin(),foo.end());

  std::cout << "The " << (last - foo.begin()) << " first elements are a valid heap:";
  for (auto it=foo.begin(); it!=last; ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

Most implementations consider a range sorted in reverse order a valid heap:
Possible output:
The 9 first elements are a valid heap: 9 8 7 6 5 4 3 2 1

10.std::is_partitioned

  • 原型:
template <class InputIterator, class UnaryPredicate>
  bool is_partitioned (InputIterator first, InputIterator last, UnaryPredicate pred);
  • 参数:
  • InputIterator first:区间的开始
  • InputIterator last:区间的结束
  • UnaryPredicate pred:自定义比较规则,可以是函数指针或者仿函数对象、lambda表达式
  • 作用:判断[first,last)区间内的所有满足pred条件的元素是否都在开始位置,且一旦出现不满足pred的元素后,后面不能再出现满足pred条件的元素
  • 返回值:满足条件返回true,反之返回false
  • 实现:
template <class InputIterator, class UnaryPredicate>
  bool is_partitioned (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  while (first!=last && pred(*first)) {
    ++first;
  }
  while (first!=last) {
    if (pred(*first)) return false;
    ++first;
  }
  return true;
}
  • 案例:
// is_partitioned example
#include      // std::cout
#include     // std::is_partitioned
#include         // std::array

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

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

  // print contents:
  std::cout << "foo:"; for (int& x:foo) std::cout << ' ' << x;
  if ( std::is_partitioned(foo.begin(),foo.end(),IsOdd) )
    std::cout << " (partitioned)\n";
  else
    std::cout << " (not partitioned)\n";

  // partition array:
  std::partition (foo.begin(),foo.end(),IsOdd);

  // print contents again:
  std::cout << "foo:"; for (int& x:foo) std::cout << ' ' << x;
  if ( std::is_partitioned(foo.begin(),foo.end(),IsOdd) )
    std::cout << " (partitioned)\n";
  else
    std::cout << " (not partitioned)\n";

  return 0;
}

Possible output:
foo: 1 2 3 4 5 6 7 (not partitioned)
foo: 1 7 3 5 4 6 2 (partitioned)

你可能感兴趣的:(C/C++)