C++合并(按排序范围运行)

一、merge

头文件algorithm

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)中的元素组合到从结果开始的新范围中,并对其所有元素进行排序。

使用operator <作为第一个版本比较元素,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++;
  }
}

参数

  1. first1,last1
    将迭代器输入到第一个排序序列的初始位置和最终位置。使用的范围是[first1,last1],它包含first1和last1之间的所有元素,包括first1指向的元素,但不包括last1指向的元素。
  2. first2,last2
    将迭代器输入到第二个排序序列的初始位置和最终位置。使用的范围是[first2,last2)。
  3. result
    将迭代器输出到存储结果组合范围的范围的初始位置。它的大小等于上述两个范围的总和。
  4. comp
    二进制函数,接受迭代器指向的两个类型的参数,并返回一个可转换为bool的值。返回的值指示第一个参数是否在其定义的特定严格弱顺序中被认为是在第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

范围不得重叠。 两个输入范围中的元素应该可以分配给result指向的范围内的元素。它们也应具有可比性(运算符<for(1),comp with(2))。

返回值

一个迭代器,指向结果序列中的past-the-end元素。

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

在这里插入图片描述

例外

如果任何元素比较,元素赋值或迭代器上的操作抛出,则抛出。请注意,无效参数会导致未定义的行为。

二、inplace_merge

头文件algorithm

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]。

使用operator <作为第一个版本比较元素,comp作为第二个版本。两个范围内的元素必须按照相同的标准(操作符<或comp)进行排序。结果范围也根据此进行排序。

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

参数

  1. first
    双向迭代器到第一个排序序列中的初始位置进行合并。这也是存储合并范围的初始位置。
  2. middle
    到第二个排序序列的初始位置的双向迭代器,因为两个序列必须是连续的,所以匹配第一个序列的过去位置。
  3. last
    双向迭代器到第二个排序序列的过去位置。这也是存储合并范围的范围的过去位置。
  4. comp
    二进制函数,接受迭代器指向的两个类型的参数,并返回一个可转换为bool的值。返回的值指示第一个参数是否在其定义的特定严格弱顺序中被认为是在第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

BidirectionalIterator应指向一个正确定义了swap的类型,它既
move-constructible又move-assignable。

返回值

没有

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

在这里插入图片描述

复杂

如果有足够的额外内存可用,则在第一个和最后一个之间的距离为线性:执行N-1次比较,最多执行两次元素移动。
否则,最多为linearithmic:执行最多N * log(N)个元素比较(其中N是上面的距离),最多可执行多个元素交换。

例外

如果任何元素比较,元素交换(或移动)或迭代器上的操作抛出,则抛出。请注意,无效参数会导致未定义的行为。

三、include

头文件algorithm

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。

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

范围内的元素应按照相同的标准(操作符<或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;
}

参数

  1. first1,last1
    将迭代器输入到第一个排序序列的初始位置和最终位置(测试它是否包含第二个序列)。使用的范围是[first1,last1],它包含first1和last1之间的所有元素,包括first1指向的元素,但不包括last1指向的元素。
  2. first2,last2
    将迭代器输入到第二个排序序列的初始位置和最终位置(测试它是否包含在第一个序列中)。使用的范围是[first2,last2)。
  3. comp
    二进制函数,接受两个元素作为参数(两个序列中的每个序列中的一个,顺序相同),并返回一个可转换为bool的值。返回的值表示作为第一个参数传递的元素是否被认为是在它定义的特定严格弱顺序中的第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

返回值

如果范围[first2,last2]中的每个元素都包含在[first1,last1]范围内,则返回true,否则返回false。
【C++ 98】
如果[first2,last2)是空范围,则结果未指定。
【C++ 11】
如果[first2,last2)为空范围,则该函数返回true。

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

在这里插入图片描述

复杂

在两个范围内最多为两倍距离的线性:执行最多2 *(count1 + count2)-1次比较(其中countX是firstX和lastX之间的距离)。

数据竞赛

访问两个范围中的一些(或所有)对象(最多两次)。

例外

如果任何元素比较(或调用comp)抛出或迭代器上的任何操作抛出,则抛出。
请注意,无效参数会导致未定义的行为。

四、set_union

头文件algorithm

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

联合两个排序范围

构造一个从result指向的位置开始的排序范围,其中包含两个排序范围[first1,last1]和[first2,last2)的set union。

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

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

范围中的元素应根据相同的标准(运算符<或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;
  }
}

参数

  1. first1,last1
    将迭代器输入到第一个排序序列的初始位置和最终位置。使用的范围是[first1,last1],它包含first1和last1之间的所有元素,包括first1指向的元素,但不包括last1指向的元素。
  2. first2,last2
    将迭代器输入到第二个排序序列的初始位置和最终位置。使用的范围是[first2,last2)。
  3. result
    将迭代器输出到存储结果序列的范围的初始位置。
    指向的类型应支持从其他范围分配元素的值。
  4. comp
    二进制函数,它接受输入迭代器指向的两个类型的参数,并返回一个可转换为bool的值。返回的值指示第一个参数是否在其定义的特定严格弱顺序中被认为是在第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

范围不得重叠。

返回值

构造范围末尾的迭代器。

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

在这里插入图片描述

五、set_intersection

头文件algorithm

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)的集合交集。

两组的交集仅由两组中存在的元素形成。 函数复制的元素始终来自第一个范围,顺序相同。

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

范围中的元素应根据相同的标准(运算符<或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;
}

参数

  1. first1,last1
    将迭代器输入到第一个排序序列的初始位置和最终位置。使用的范围是[first1,last1],它包含first1和last1之间的所有元素,包括first1指向的元素,但不包括last1指向的元素。
  2. first2,last2
    将迭代器输入到第二个排序序列的初始位置和最终位置。使用的范围是[first2,last2)。
  3. result
    将迭代器输出到存储结果序列的范围的初始位置。
    指向类型应支持从第一个范围分配元素的值。
  4. comp
    二进制函数,它接受输入迭代器指向的两个类型的参数,并返回一个可转换为bool的值。返回的值指示第一个参数是否在其定义的特定严格弱顺序中被认为是在第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

范围不得重叠。

返回值

构造范围末尾的迭代器。

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

在这里插入图片描述

六、set_difference

头文件algorithm

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

两个排序范围的差异

构造从结果指向的位置开始的排序范围,其中排序范围[first1,last1]的设置差异相对于排序范围[first2,last2]。

两组的差异由第一组中存在的元素形成,但不存在于第二组中。函数复制的元素始终来自第一个范围,顺序相同。

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

请注意,这是一个方向性操作 - 对于对称等效,请参阅set_symmetric_difference。

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

范围中的元素应根据相同的标准(运算符<或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);
}

参数

  1. first1,last1
    将迭代器输入到第一个排序序列的初始位置和最终位置。使用的范围是[first1,last1],它包含first1和last1之间的所有元素,包括first1指向的元素,但不包括last1指向的元素。
  2. first2,last2
    将迭代器输入到第二个排序序列的初始位置和最终位置。使用的范围是[first2,last2)。
  3. result
    将迭代器输出到存储结果序列的范围的初始位置。
    指向类型应支持从第一个范围分配元素的值。
  4. comp
    二进制函数,它接受输入迭代器指向的两个类型的参数,并返回一个可转换为bool的值。返回的值指示第一个参数是否在其定义的特定严格弱顺序中被认为是在第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

范围不得重叠。

返回值

构造范围末尾的迭代器。

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

在这里插入图片描述

七、set_symmetric_difference

头文件algorithm

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

两个排序范围的对称差异

构造一个从result指向的位置开始的排序范围,其中包含两个排序范围[first1,last1]和[first2,last2)的设置对称差异。

两组的对称差异由一组中存在的元素形成,而另一组中不存在。 在每个范围中的等效元素中,丢弃的那些是在调用之前以现有顺序出现的那些元素。 还会为复制的元素保留现有顺序。

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

范围中的元素应根据相同的标准(运算符<或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; }
  }
}

参数

  1. first1,last1
    将迭代器输入到第一个排序序列的初始位置和最终位置。使用的范围是[first1,last1],它包含first1和last1之间的所有元素,包括first1指向的元素,但不包括last1指向的元素。
  2. first2,last2
    将迭代器输入到第二个排序序列的初始位置和最终位置。使用的范围是[first2,last2)。
  3. result
    将迭代器输出到存储结果序列的范围的初始位置。
    指向的类型应支持从其他范围分配元素的值。
  4. comp
    二进制函数,它接受输入迭代器指向的两个类型的参数,并返回一个可转换为bool的值。返回的值指示第一个参数是否在其定义的特定严格弱顺序中被认为是在第二个参数之前。
    该函数不得修改其任何参数。这可以是函数指针或函数对象。

范围不得重叠。

返回值

构造范围末尾的迭代器。

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

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值