C++ set_union(STL set_union)算法详解

  • 内容
  • 评论
  • 相关

第一个版本的 set_union() 函数模板实现了集合的并集运算,它需要 5 个参数:两个迭代器用来指定左操作数的集合范围,另两个迭代器用来作为右操作数的集合范围,还有一个迭代器用来指向结果集合的存放位置。例如:

std::vector<int> set1 {1, 2, 3, 4, 5, 6};
std::vector<int> set2 {4, 5, 6, 7, 8, 9};
std::vector<int> result;
std::set_union(std::begin (set1), std::end(set1), // Range for set that is left operand
std::begin(set2), std::end(set2), // Range for set that is right operand
std::back_inserter(result));    // Destination for the result:1 2 3 4 5 6 7 8 9

set1 和 set2 中的初始值都是升序。如果它们都不是,那么在使用 set_union() 算法前,需要对 vector 容器排序。前面章节中介绍的 back_inserter() 函数模板定义在 iterator 头文件中,它会调用传入参数的函数 push_back() 来返回一个 back_inserter_iterator 对象。所以,set1 和 set2 并集中的元素会被保存在 result 中。从并集运算得到的元素集合是容器元素的副本,因此这个运算并不会影响容器的原始内容。

当然,如果不保存运算结果;可以用一个流迭代器输出这些元素:

std::set_union(std::begin(set1), std::end(set1), std::begin(set2), std::end(set2),std::ostream_iterator<int> {std::cout, " "});

这里的目的地址是一个 ostream_iterator,它可以将结果输出到标准输出流中。

第二个版本的 set_union() 函数模板接收的第 6 个参数是一个用来比较集合元素的函数对象。下面是它可能的一些用法:

std:: set<int, std::greater<int>>set1 {1, 2, 3, 4, 5, 6}; // Contains 6 5 4 3 2 1
std:: set<int, std:: greater<int>>set2 {4, 5, 6, 7, 8, 9}; // Contains 9 8 7 6 5 4
std::set<int, std::greater<int>>result; // Elements in descending sequence
std::set_union(std::begin(set1), std::end(set1),std::begin(set2), std::end(set2),std::inserter(result, std::begin(result)), // Result destination: 9 8 7 6 5 4 3 2 1
std::greater<int>()); // Function object for comparing elements

这一次的集合是 set 容器中的元素。这些元素是用函数对象 greater<int> 排序过的,因此它们都是升序。set_union() 的最后一个参数是一个用来比较集合元素的 greater<int> 类型的实例。结果的存放位置是 result 容器的 inserter_iterator,容器会调用成员函数 insert() 来添加元素。不能对 set 容器使用 back_insert_iterator,因为它没有成员函数 push_back()。并集运算的结果是从两个集合得到的元素的副本的降序集合。

这两个版本的 set_union() 函数都会返回一个指向被复制元素段末尾后一个位置的迭代器。如果目的容器包含操作前的元素,这是很有用的。例如,如果目的容器是 vector 容器,set_union() 用 front_insert_iterator,如果用 back_inserter_iterator,可以用这个容器的结束迭代器,插入这个新元素,set_union() 返回的迭代器会指向第一个原始元素。

本文标题:C++ set_union(STL set_union)算法详解

本文地址:http://www.hosteonscn.com/2952.html

评论

0条评论

发表评论

邮箱地址不会被公开。 必填项已用*标注