STL-algorithm-4

Merge (operating on sorted ranges)

merge

default (1)
template <class InputIterator1, class InputIterator2, class OutputIterator>  OutputIterator merge (InputIterator1 first1, InputIterator1 last1,                        InputIterator2 first2, InputIterator2 last2,                        OutputIterator result);
custom (2)
template <class InputIterator1, class InputIterator2,          class OutputIterator, class Compare>  OutputIterator merge (InputIterator1 first1, InputIterator1 last1,                        InputIterator2 first2, InputIterator2 last2,                        OutputIterator result, Compare comp);

合并已排序的范围

将排序范围[first1,last1)和[first2,last2)中的元素组合到一个新的范围中,从result开始,所有元素都已排序。 第一个版本使用运算符<比较元素,第二个版本使用comp比较元素。两个范围内的元素应已根据相同的标准进行排序(运算符<或comp)。生成的范围也会根据此进行排序。

template <class InputIterator1, class InputIterator2, class OutputIterator>
  OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
                        InputIterator2 first2, InputIterator2 last2,
                        OutputIterator result)
{
  while (true) {
    if (first1==last1) return std::copy(first2,last2,result);
    if (first2==last2) return std::copy(first1,last1,result);
    *result++ = (*first2<*first1)? *first2++ : *first1++;
  }
}
// merge algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::merge, std::sort
#include <vector>       // std::vector

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

  std::sort (first,first+5);
  std::sort (second,second+5);
  std::merge (first,first+5,second,second+5,v.begin());

  std::cout << "The resulting vector contains:";
  for (std::vector<int>::iterator 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

inplace_merge

default (1)
template <class BidirectionalIterator>  void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle,                      BidirectionalIterator last);
custom (2)
template <class BidirectionalIterator, class Compare>  void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle,                      BidirectionalIterator last, Compare comp);

合并连续排序的范围

合并两个连续的排序范围:[first,middle)和[middle,last),将结果放入组合的排序范围[first,last)。

第一个版本使用运算符<比较元素,第二个版本使用comp比较元素。两个范围内的元素应已根据相同的标准进行排序(运算符<或comp)。生成的范围也会根据此进行排序。

该函数保留具有等效值的元素的相对顺序,第一个范围中的元素在第二个范围中等效的元素之前。

// inplace_merge example
#include <iostream>     // std::cout
#include <algorithm>    // std::inplace_merge, std::sort, std::copy
#include <vector>       // 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;

  std::sort (first,first+5);
  std::sort (second,second+5);

  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

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

测试排序的范围是否包括另一个排序的范围

如果已排序的范围[first1,last1)包含已排序范围[first2,last2)中的所有元素,则返回true。

第一个版本使用运算符<比较元素,第二个版本使用comp比较元素。两个元素a和b被认为是等价的,如果(!(a<b)&&!(b<a))或如果(!comp(a,b)&&!comp(b,a))。

该范围内的元素应已根据相同的标准进行排序(运算符<或comp)。

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 <iostream>     // std::cout
#include <algorithm>    // 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!

set_union

default (1)
template <class InputIterator1, class InputIterator2, class OutputIterator>  OutputIterator set_union (InputIterator1 first1, InputIterator1 last1,                            InputIterator2 first2, InputIterator2 last2,                            OutputIterator result);
custom (2)
template <class InputIterator1, class InputIterator2,          class OutputIterator, class Compare>  OutputIterator set_union (InputIterator1 first1, InputIterator1 last1,                            InputIterator2 first2, InputIterator2 last2,                            OutputIterator result, Compare comp);

两个排序范围的并集

用两个排序范围[first1,last1)和[first2,last2)的集合并集,构造一个从result指向的位置开始的排序范围。

两个集合的并集是由存在于其中一个集合或两个集合中的元素形成的。第二个范围中在第一个范围中具有等效元素的元素不会复制到结果范围中。

第一个版本使用运算符<比较元素,第二个版本使用comp比较元素。两个元素a和b被认为是等价的,如果(!(a<b)&&!(b<a))或如果(!comp(a,b)&&!comp(b,a))。

范围内的元素应已根据相同的标准进行排序(运算符<或comp)。生成的范围也会根据此进行排序。

template <class InputIterator1, class InputIterator2, class OutputIterator>
  OutputIterator set_union (InputIterator1 first1, InputIterator1 last1,
                            InputIterator2 first2, InputIterator2 last2,
                            OutputIterator result)
{
  while (true)
  {
    if (first1==last1) return std::copy(first2,last2,result);
    if (first2==last2) return std::copy(first1,last1,result);

    if (*first1<*first2) { *result = *first1; ++first1; }
    else if (*first2<*first1) { *result = *first2; ++first2; }
    else { *result = *first1; ++first1; ++first2; }
    ++result;
  }
}
// set_union example
#include <iostream>     // std::cout
#include <algorithm>    // std::set_union, std::sort
#include <vector>       // std::vector

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

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

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

  std::cout << "The union has " << (v.size()) << " elements:\n";
  for (it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}
Output:
The union has 8 elements:
 5 10 15 20 25 30 40 50

set_intersection

default (1)
template <class InputIterator1, class InputIterator2, class OutputIterator>  OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1,                                   InputIterator2 first2, InputIterator2 last2,                                   OutputIterator result);
custom (2)
template <class InputIterator1, class InputIterator2,          class OutputIterator, class Compare>  OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1,                                   InputIterator2 first2, InputIterator2 last2,                                   OutputIterator result, Compare comp);

两个排序范围的交集

构造一个排序范围,从result指向的位置开始,并设置两个排序范围[first1,last1)和[first2,last2)的交集。

两个集合的交集仅由两个集合中存在的元素形成。函数复制的元素总是以相同的顺序来自第一个范围。

第一个版本使用运算符<比较元素,第二个版本使用comp比较元素。两个元素a和b被认为是等价的,如果(!(a<b)&&!(b<a))或如果(!comp(a,b)&&!comp(b,a))。

范围内的元素应已根据相同的标准进行排序(运算符<或comp)。生成的范围也会根据此进行排序。

template <class InputIterator1, class InputIterator2, class OutputIterator>
  OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1,
                                   InputIterator2 first2, InputIterator2 last2,
                                   OutputIterator result)
{
  while (first1!=last1 && first2!=last2)
  {
    if (*first1<*first2) ++first1;
    else if (*first2<*first1) ++first2;
    else {
      *result = *first1;
      ++result; ++first1; ++first2;
    }
  }
  return result;
}
// set_intersection example
#include <iostream>     // std::cout
#include <algorithm>    // std::set_intersection, std::sort
#include <vector>       // std::vector

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

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

  it=std::set_intersection (first, first+5, second, second+5, v.begin());
                                               // 10 20 0  0  0  0  0  0  0  0
  v.resize(it-v.begin());                      // 10 20

  std::cout << "The intersection has " << (v.size()) << " elements:\n";
  for (it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
The intersection has 2 elements:
 10 20

set_difference

default (1)
template <class InputIterator1, class InputIterator2, class OutputIterator>  OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1,                                 InputIterator2 first2, InputIterator2 last2,                                 OutputIterator result);
custom (2)
template <class InputIterator1, class InputIterator2,          class OutputIterator, class Compare>  OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1,                                 InputIterator2 first2, InputIterator2 last2,                                 OutputIterator result, Compare comp);

两个排序范围的差异

构造一个排序范围,从result指向的位置开始,并设置排序范围[first1,last1)相对于排序范围[f1st2,last2)的差值。

两个集合的差异是由第一个集合中存在的元素形成的,而不是第二个集合中的元素。函数复制的元素总是以相同的顺序来自第一个范围。

对于支持一个值多次出现的容器,差异包括给定值在第一个范围内的出现次数,减去第二个保留顺序中匹配元素的数量。

请注意,这是一个定向操作-有关对称等效项,请参见set_symmetric_difference。

第一个版本使用运算符<比较元素,第二个版本使用comp比较元素。两个元素a和b被认为是等价的,如果(!(a<b)&&!(b<a))或如果(!comp(a,b)&&!comp(b,a))。

范围内的元素应已根据相同的标准进行排序(运算符<或comp)。生成的范围也会根据此进行排序。 

template <class InputIterator1, class InputIterator2, class OutputIterator>
  OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1,
                                 InputIterator2 first2, InputIterator2 last2,
                                 OutputIterator result)
{
  while (first1!=last1 && first2!=last2)
  {
    if (*first1<*first2) { *result = *first1; ++result; ++first1; }
    else if (*first2<*first1) ++first2;
    else { ++first1; ++first2; }
  }
  return std::copy(first1,last1,result);
}
// set_difference example
#include <iostream>     // std::cout
#include <algorithm>    // std::set_difference, std::sort
#include <vector>       // std::vector

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

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

  it=std::set_difference (first, first+5, second, second+5, v.begin());
                                               //  5 15 25  0  0  0  0  0  0  0
  v.resize(it-v.begin());                      //  5 15 25

  std::cout << "The difference has " << (v.size()) << " elements:\n";
  for (it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}Output:
The difference has 3 elements:
 5 15 25

set_symmetric_difference

default (1)
template <class InputIterator1, class InputIterator2, class OutputIterator>  OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1,                                           InputIterator2 first2, InputIterator2 last2,                                           OutputIterator result);
custom (2)
template <class InputIterator1, class InputIterator2,          class OutputIterator, class Compare>  OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1,                                           InputIterator2 first2, InputIterator2 last2,                                           OutputIterator result, Compare comp);

两个排序范围的对称差

用两个排序范围[first1,last1)和[first2,last2)的集合对称差,构造一个从result所指向的位置开始的排序范围。

两个集合的对称差是由存在于其中一个集合中但不存在于另一个集合的元素形成的。在每个范围中的等效元素中,被丢弃的元素是在调用之前按现有顺序出现的元素。对于复制的图元,也会保留现有顺序。

第一个版本使用运算符<比较元素,第二个版本使用comp比较元素。两个元素a和b被认为是等价的,如果(!(a<b)&&!(b<a))或如果(!comp(a,b)&&!comp(b,a))。

范围内的元素应已根据相同的标准进行排序(运算符<或comp)。生成的范围也会根据此进行排序。

template <class InputIterator1, class InputIterator2, class OutputIterator>
  OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1,
                                           InputIterator2 first2, InputIterator2 last2,
                                           OutputIterator result)
{
  while (true)
  {
    if (first1==last1) return std::copy(first2,last2,result);
    if (first2==last2) return std::copy(first1,last1,result);

    if (*first1<*first2) { *result=*first1; ++result; ++first1; }
    else if (*first2<*first1) { *result = *first2; ++result; ++first2; }
    else { ++first1; ++first2; }
  }
}
// set_symmetric_difference example
#include <iostream>     // std::cout
#include <algorithm>    // std::set_symmetric_difference, std::sort
#include <vector>       // std::vector

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

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

  it=std::set_symmetric_difference (first, first+5, second, second+5, v.begin());
                                               //  5 15 25 30 40 50  0  0  0  0
  v.resize(it-v.begin());                      //  5 15 25 30 40 50

  std::cout << "The symmetric difference has " << (v.size()) << " elements:\n";
  for (it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}
Output:
The symmetric difference has 6 elements:
 5 15 25 30 40 50

Heap

push_heap

default (1)
template <class RandomAccessIterator>  void push_heap (RandomAccessIterator first, RandomAccessIterator last);
custom (2)
template <class RandomAccessIterator, class Compare>  void push_heap (RandomAccessIterator first, RandomAccessIterator last,                   Compare comp);

将元素推入堆范围

给定范围为[first,last-1)的堆,此函数通过将(last-1)中的值放入堆中相应的位置,将堆的范围扩展到[first、last)。

可以通过调用make_heap将范围组织成一个堆。之后,如果分别使用push_heap和pop_heap添加元素和从中删除元素,则保留其堆属性。

// range heap example
#include <iostream>     // std::cout
#include <algorithm>    // std::make_heap, std::pop_heap, std::push_heap, std::sort_heap
#include <vector>       // std::vector

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

  std::make_heap (v.begin(),v.end());
  std::cout << "initial max heap   : " << v.front() << '\n';

  std::pop_heap (v.begin(),v.end()); v.pop_back();
  std::cout << "max heap after pop : " << v.front() << '\n';

  v.push_back(99); std::push_heap (v.begin(),v.end());
  std::cout << "max heap after push: " << v.front() << '\n';

  std::sort_heap (v.begin(),v.end());

  std::cout << "final sorted range :";
  for (unsigned i=0; i<v.size(); i++)
    std::cout << ' ' << v[i];

  std::cout << '\n';

  return 0;
}Output:
initial max heap   : 30
max heap after pop : 20
max heap after push: 99
final sorted range : 5 10 15 20 99

pop_heap

default (1)
template <class RandomAccessIterator>  void pop_heap (RandomAccessIterator first, RandomAccessIterator last);
custom (2)
template <class RandomAccessIterator, class Compare>  void pop_heap (RandomAccessIterator first, RandomAccessIterator last,                 Compare comp);

从堆范围弹出元素

重新排列堆范围[first,last)中的元素,使被视为堆的部分缩短一:具有最高值的元素移动到(last-1)。

当具有最高值的元素从first移动到(last-1)(现在不在堆中)时,其他元素会以这样的方式重新组织,即范围[first,last-1)保留堆的属性。

可以通过调用make_heap将范围组织成一个堆。之后,如果分别使用push_heap和pop_heap添加元素和从中删除元素,则保留其堆属性。

// range heap example
#include <iostream>     // std::cout
#include <algorithm>    // std::make_heap, std::pop_heap, std::push_heap, std::sort_heap
#include <vector>       // std::vector

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

  std::make_heap (v.begin(),v.end());
  std::cout << "initial max heap   : " << v.front() << '\n';

  std::pop_heap (v.begin(),v.end()); v.pop_back();
  std::cout << "max heap after pop : " << v.front() << '\n';

  v.push_back(99); std::push_heap (v.begin(),v.end());
  std::cout << "max heap after push: " << v.front() << '\n';

  std::sort_heap (v.begin(),v.end());

  std::cout << "final sorted range :";
  for (unsigned i=0; i<v.size(); i++)
    std::cout << ' ' << v[i];

  std::cout << '\n';

  return 0;
}

Output:

initial max heap   : 30
max heap after pop : 20
max heap after push: 99
final sorted range : 5 10 15 20 99

make_heap

default (1)
template <class RandomAccessIterator>  void make_heap (RandomAccessIterator first, RandomAccessIterator last);
custom (2)
template <class RandomAccessIterator, class Compare>  void make_heap (RandomAccessIterator first, RandomAccessIterator last,                  Compare comp );

从范围生成堆

以形成堆的方式重新排列范围[first,last)中的元素。

堆是一种组织范围内元素的方式,它允许在任何时候快速检索具有最高值的元素(使用pop_heap),甚至重复检索,同时允许快速插入新元素(使用push_heap。 具有最高值的元素总是由第一个指向。

其他元素的顺序取决于特定的实现,但在该头的所有与堆相关的函数中都是一致的。

使用运算符<(对于第一个版本)或comp(对于第二个版本)对元素进行比较:与范围中的其他元素相比,值最高的元素将返回false。

标准容器适配器priority_queue自动调用make_heap、push_heap和pop_heap来维护容器的堆属性。

// range heap example
#include <iostream>     // std::cout
#include <algorithm>    // std::make_heap, std::pop_heap, std::push_heap, std::sort_heap
#include <vector>       // std::vector

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

  std::make_heap (v.begin(),v.end());
  std::cout << "initial max heap   : " << v.front() << '\n';

  std::pop_heap (v.begin(),v.end()); v.pop_back();
  std::cout << "max heap after pop : " << v.front() << '\n';

  v.push_back(99); std::push_heap (v.begin(),v.end());
  std::cout << "max heap after push: " << v.front() << '\n';

  std::sort_heap (v.begin(),v.end());

  std::cout << "final sorted range :";
  for (unsigned i=0; i<v.size(); i++)
    std::cout << ' ' << v[i];

  std::cout << '\n';

  return 0;
}Output:
initial max heap   : 30
max heap after pop : 20
max heap after push: 99
final sorted range : 5 10 15 20 99

sort_heap

default (1)
template <class RandomAccessIterator>  void sort_heap (RandomAccessIterator first, RandomAccessIterator last);
custom (2)
template <class RandomAccessIterator, class Compare>  void sort_heap (RandomAccessIterator first, RandomAccessIterator last,                  Compare comp);

对堆的元素进行排序

按升序对堆范围 [first,last)中的元素进行排序。 第一个版本使用运算符<比较元素,第二个版本使用comp比较元素,这与构建堆时使用的运算符相同。 该范围将丢失其作为堆的属性。

// range heap example
#include <iostream>     // std::cout
#include <algorithm>    // std::make_heap, std::pop_heap, std::push_heap, std::sort_heap
#include <vector>       // std::vector

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

  std::make_heap (v.begin(),v.end());
  std::cout << "initial max heap   : " << v.front() << '\n';

  std::pop_heap (v.begin(),v.end()); v.pop_back();
  std::cout << "max heap after pop : " << v.front() << '\n';

  v.push_back(99); std::push_heap (v.begin(),v.end());
  std::cout << "max heap after push: " << v.front() << '\n';

  std::sort_heap (v.begin(),v.end());

  std::cout << "final sorted range :";
  for (unsigned i=0; i<v.size(); i++)
    std::cout << ' ' << v[i];

  std::cout << '\n';

  return 0;
}Output:
initial max heap   : 30
max heap after pop : 20
max heap after push: 99
final sorted range : 5 10 15 20 99

is_heap

default (1)
template <class RandomAccessIterator>  bool is_heap (RandomAccessIterator first, RandomAccessIterator last);
custom (2)
template <class RandomAccessIterator, class Compare>  bool is_heap (RandomAccessIterator first, RandomAccessIterator last,                Compare comp);

测试范围是否为堆

如果范围[first,last)形成堆,则返回true,如同使用make_heap构造一样。 第一个版本使用运算符<比较元素,第二个版本使用comp比较元素。

// is_heap example
#include <iostream>     // std::cout
#include <algorithm>    // std::is_heap, std::make_heap, std::pop_heap
#include <vector>       // 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

is_heap_until

default (1)
template <class RandomAccessIterator>  RandomAccessIterator is_heap_until (RandomAccessIterator first,                                      RandomAccessIterator last);
custom (2)
template <class RandomAccessIterator, class Compare>  RandomAccessIterator is_heap_until (RandomAccessIterator first,                                      RandomAccessIterator last                                      Compare comp);

查找第一个不按堆顺序排列的元素

将迭代器返回到范围[first,last)中的第一个元素,如果该范围被视为堆(就像用make_heap构造的一样),则该元素不在有效位置。 第一个和返回的迭代器之间的范围是一个堆。 如果整个范围是一个有效的堆,则函数返回最后一个。 第一个版本使用运算符<比较元素,第二个版本使用comp比较元素。

// is_heap example
#include <iostream>     // std::cout
#include <algorithm>    // std::is_heap_until, std::sort, std::reverse
#include <vector>       // 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

Min/max

min

default (1)
template <class T> constexpr const T& min (const T& a, const T& b);
custom (2)
template <class T, class Compare>  constexpr const T& min (const T& a, const T& b, Compare comp);
initializer list (3)
template <class T> constexpr T min (initializer_list<T> il);template <class T, class Compare>  constexpr T min (initializer_list<T> il, Compare comp);

返回最小值

返回a和b中最小的一个。如果两者相等,则返回a。 初始值设定项列表(3)的版本返回列表中所有元素中最小的一个。如果它们不止一个,则返回第一个。 函数使用运算符<(或comp,如果提供)来比较这些值。

// min example
#include <iostream>     // std::cout
#include <algorithm>    // std::min

int main () {
  std::cout << "min(1,2)==" << std::min(1,2) << '\n';
  std::cout << "min(2,1)==" << std::min(2,1) << '\n';
  std::cout << "min('a','z')==" << std::min('a','z') << '\n';
  std::cout << "min(3.14,2.72)==" << std::min(3.14,2.72) << '\n';
  return 0;
}
Output:
min(1,2)==1
min(2,1)==1
min('a','z')==a
min(3.14,2.72)==2.72

max

default (1)
template <class T> constexpr const T& max (const T& a, const T& b);
custom (2)
template <class T, class Compare>  constexpr const T& max (const T& a, const T& b, Compare comp);
initializer list (3)
template <class T> constexpr T max (initializer_list<T> il);template <class T, class Compare>  constexpr T max (initializer_list<T> il, Compare comp);

返回最大值

返回a和b中的最大值。如果两者相等,则返回a。 初始值设定项列表(3)的版本返回列表中所有元素中最大的一个。如果它们不止一个,则返回第一个。 函数使用运算符<(或comp,如果提供)来比较这些值。

// max example
#include <iostream>     // std::cout
#include <algorithm>    // std::max

int main () {
  std::cout << "max(1,2)==" << std::max(1,2) << '\n';
  std::cout << "max(2,1)==" << std::max(2,1) << '\n';
  std::cout << "max('a','z')==" << std::max('a','z') << '\n';
  std::cout << "max(3.14,2.73)==" << std::max(3.14,2.73) << '\n';
  return 0;
}Output:
max(1,2)==2
max(2,1)==2
max('a','z')==z
max(3.14,2.73)==3.14

minmax

default (1)
template <class T>  constexpr pair <const T&,const T&> minmax (const T& a, const T& b);
custom (2)
template <class T, class Compare>  constexpr pair <const T&,const T&> minmax (const T& a, const T& b, Compare comp);
initializer list (3)
template <class T>  constexpr pair<T,T> minmax (initializer_list<T> il);template <class T, class Compare>  constexpr pair<T,T> minmax (initializer_list<T> il, Compare comp);

返回最小和最大元素

返回一对,其中a和b中最小的作为第一个元素,最大的作为第二个元素。如果两者相等,则函数返回make_pair(a,b)。 初始值设定项列表(3)的版本返回一对,其中列表中所有元素中最小的元素作为第一个元素(如果有多个,则为第一个),最大的元素作为第二个(如果有一个以上,则为最后一个)。 函数使用运算符<(或comp,如果提供)来比较这些值。

// minmax example
#include <iostream>     // std::cout
#include <algorithm>    // std::minmax

int main () {
  auto result = std::minmax({1,2,3,4,5});

  std::cout << "minmax({1,2,3,4,5}): ";
  std::cout << result.first << ' ' << result.second << '\n';
  return 0;
}Output:
minmax({1,2,3,4,5}): 1 5

min_element

default (1)
template <class ForwardIterator>  ForwardIterator min_element (ForwardIterator first, ForwardIterator last);
custom (2)
template <class ForwardIterator, class Compare>  ForwardIterator min_element (ForwardIterator first, ForwardIterator last,                               Compare comp);

返回范围内最小的元素

返回一个迭代器,该迭代器指向[first,last)范围内值最小的元素。

对第一个版本使用运算符<或对第二个版本使用comp进行比较;如果没有其他元素比它小,则元素是最小的。如果有多个元素满足此条件,则迭代器返回的点指向这些元素中的第一个。

template <class ForwardIterator>
  ForwardIterator min_element ( ForwardIterator first, ForwardIterator last )
{
  if (first==last) return last;
  ForwardIterator smallest = first;

  while (++first!=last)
    if (*first<*smallest)    // or: if (comp(*first,*smallest)) for version (2)
      smallest=first;
  return smallest;
}
// min_element/max_element example
#include <iostream>     // std::cout
#include <algorithm>    // std::min_element, std::max_element

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

struct myclass {
  bool operator() (int i,int j) { return i<j; }
} myobj;

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

  // using default comparison:
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7) << '\n';

  // using function myfn as comp:
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myfn) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7,myfn) << '\n';

  // using object myobj as comp:
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myobj) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7,myobj) << '\n';

  return 0;
}Output:
The smallest element is 2
The largest element is 9
The smallest element is 2
The largest element is 9
The smallest element is 2
The largest element is 9

max_element

default (1)
template <class ForwardIterator>  ForwardIterator max_element (ForwardIterator first, ForwardIterator last);
custom (2)
template <class ForwardIterator, class Compare>  ForwardIterator max_element (ForwardIterator first, ForwardIterator last,                               Compare comp);

返回范围内的最大元素

返回一个迭代器,该迭代器指向范围[first,last)中值最大的元素。 对第一个版本使用运算符<或对第二个版本使用comp进行比较;如果没有其他元素的比较小于某个元素,则该元素是最大的。如果有多个元素满足此条件,则迭代器返回的点指向这些元素中的第一个。

template <class ForwardIterator>
  ForwardIterator max_element ( ForwardIterator first, ForwardIterator last )
{
  if (first==last) return last;
  ForwardIterator largest = first;

  while (++first!=last)
    if (*largest<*first)    // or: if (comp(*largest,*first)) for version (2)
      largest=first;
  return largest;
}
// min_element/max_element example
#include <iostream>     // std::cout
#include <algorithm>    // std::min_element, std::max_element

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

struct myclass {
  bool operator() (int i,int j) { return i<j; }
} myobj;

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

  // using default comparison:
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7) << '\n';

  // using function myfn as comp:
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myfn) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7,myfn) << '\n';

  // using object myobj as comp:
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myobj) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7,myobj) << '\n';

  return 0;
}
Output:
The smallest element is 2
The largest element is 9
The smallest element is 2
The largest element is 9
The smallest element is 2
The largest element is 9

minmax_element

default (1)
template <class ForwardIterator>  pair<ForwardIterator,ForwardIterator>    minmax_element (ForwardIterator first, ForwardIterator last);
custom (2)
template <class ForwardIterator, class Compare>  pair<ForwardIterator,ForwardIterator>    minmax_element (ForwardIterator first, ForwardIterator last, Compare comp);

返回范围内最小和最大的元素

返回一对,迭代器指向范围[first,last)中最小值作为第一个元素,最大值作为第二个元素的元素。 第一个版本使用运算符<进行比较,第二个版本使用comp进行比较。 如果一个以上的等效元素具有最小值,则第一个迭代器指向这些元素中的第一个。 如果一个以上的等效元素具有最大值,则第二个迭代器指向这些元素中的最后一个。

// minmax_element
#include <iostream>     // std::cout
#include <algorithm>    // std::minmax_element
#include <array>        // std::array

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

  auto result = std::minmax_element (foo.begin(),foo.end());

  // print result:
  std::cout << "min is " << *result.first;
  std::cout << ", at position " << (result.first-foo.begin()) << '\n';
  std::cout << "max is " << *result.second;
  std::cout << ", at position " << (result.second-foo.begin()) << '\n';

  return 0;
}
Output:
min is 2, at position 2
max is 9, at position 3

Other

lexicographical_compare

default (1)
template <class InputIterator1, class InputIterator2>  bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1,                                InputIterator2 first2, InputIterator2 last2);
custom (2)
template <class InputIterator1, class InputIterator2, class Compare>  bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1,                                InputIterator2 first2, InputIterator2 last2,                                Compare comp);

词汇学少于比较

如果范围[first1,last1)在字典上的比较小于范围[first2,last2),则返回true。 词典学比较是一种通常用于按字典中的字母顺序对单词进行排序的比较;它包括按顺序将两个范围中具有相同位置的元素相互比较,直到一个元素与另一个元素不相等。比较这些第一不匹配元素的结果是词典学比较的结果。 如果两个序列比较相等,直到其中一个结束,则较短的序列在字典上小于较长的序列。 第一个版本使用运算符<比较元素,第二个版本使用comp比较元素。两个元素a和b被认为是等价的,如果(!(a<b)&&!(b<a))或如果(!comp(a,b)&&!comp(b,a))。

template <class InputIterator1, class InputIterator2>
  bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1,
                                InputIterator2 first2, InputIterator2 last2)
{
  while (first1!=last1)
  {
    if (first2==last2 || *first2<*first1) return false;
    else if (*first1<*first2) return true;
    ++first1; ++first2;
  }
  return (first2!=last2);
}
// lexicographical_compare example
#include <iostream>     // std::cout, std::boolalpha
#include <algorithm>    // std::lexicographical_compare
#include <cctype>       // std::tolower

// a case-insensitive comparison function:
bool mycomp (char c1, char c2)
{ return std::tolower(c1)<std::tolower(c2); }

int main () {
  char foo[]="Apple";
  char bar[]="apartment";

  std::cout << std::boolalpha;

  std::cout << "Comparing foo and bar lexicographically (foo<bar):\n";

  std::cout << "Using default comparison (operator<): ";
  std::cout << std::lexicographical_compare(foo,foo+5,bar,bar+9);
  std::cout << '\n';

  std::cout << "Using mycomp as comparison object: ";
  std::cout << std::lexicographical_compare(foo,foo+5,bar,bar+9,mycomp);
  std::cout << '\n';

  return 0;
}The default comparison compares plain ASCII character codes, where 'A'(65) compares less than 'a'(97).
Our mycomp function transforms the letters to lowercase before comparing them, so here the first letter not matching is the third ('a'vs 'p').

Output:
Comparing foo and bar lexicographically (foo<bar):
Using default comparison (operator<): true
Using mycomp as comparison object: false

next_permutation

default (1)
template <class BidirectionalIterator>  bool next_permutation (BidirectionalIterator first,                         BidirectionalIterator last);
custom (2)
template <class BidirectionalIterator, class Compare>  bool next_permutation (BidirectionalIterator first,                         BidirectionalIterator last, Compare comp);

将范围转换为下一个排列

将范围[first,last) 中的元素重新排列到下一个字典上更大的排列中。 置换是N!元素可以采用的可能排列(其中N是该范围内的元素数量)。不同的排列可以根据它们在词典学上的相互比较来排序;第一个这样排序的可能排列(在字典上比所有其他排列小的排列)是所有元素按升序排序的排列,最大的排列所有元素按降序排序。 单个元素的比较是使用运算符<(对于第一个版本)或comp(对于第二个版本)执行的。 如果函数可以确定下一个更高的排列,那么它会按原样重新排列元素并返回true。如果这是不可能的(因为它已经处于最大可能的排列),它会根据第一个排列(按升序排序)重新排列元素,并返回false。

// next_permutation example
#include <iostream>     // std::cout
#include <algorithm>    // std::next_permutation, std::sort

int main () {
  int myints[] = {1,2,3};

  std::sort (myints,myints+3);

  std::cout << "The 3! possible permutations with 3 elements:\n";
  do {
    std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';
  } while ( std::next_permutation(myints,myints+3) );

  std::cout << "After loop: " << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';

  return 0;
}Output:
The 3! possible permutations with 3 elements:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
After loop: 1 2 3

prev_permutation

default (1)
template <class BidirectionalIterator>  bool prev_permutation (BidirectionalIterator first,                         BidirectionalIterator last );
custom (2)
template <class BidirectionalIterator, class Compare>  bool prev_permutation (BidirectionalIterator first,                         BidirectionalIterator last, Compare comp);

将范围转换为上一个排列

将范围 [first,last) 中的元素重新排列为先前的字典顺序排列。 置换是N!元素可以采用的可能排列(其中N是该范围内的元素数量)。不同的排列可以根据它们在词典学上的相互比较来排序;第一个这样排序的可能排列(在字典上比所有其他排列小的排列)是所有元素按升序排序的排列,最大的排列所有元素按降序排序。 单个元素的比较是使用运算符<(对于第一个版本)或comp(对于第二个版本)执行的。 如果函数可以确定先前的排列,那么它会按原样重新排列元素并返回true。如果这是不可能的(因为它已经处于最低可能的排列),它会根据最后一个排列(按降序排序)重新排列元素,并返回false。

// next_permutation example
#include <iostream>     // std::cout
#include <algorithm>    // std::next_permutation, std::sort, std::reverse

int main () {
  int myints[] = {1,2,3};

  std::sort (myints,myints+3);
  std::reverse (myints,myints+3);

  std::cout << "The 3! possible permutations with 3 elements:\n";
  do {
    std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';
  } while ( std::prev_permutation(myints,myints+3) );

  std::cout << "After loop: " << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';

  return 0;
}Output:
3 2 1
3 1 2
2 3 1
2 1 3
1 3 2
1 2 3
After loop: 3 2 1
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值