迭代器由 set_union() 返回

Iterator returned by set_union()

本文关键字:返回 union set 迭代器      更新时间:2023-10-16

我有以下使用算法 stl(set_union() 的代码C++:

 9     int first[] = {5, 10, 15, 20, 25};
10     int second[] = {50, 40, 30, 20, 10};
11     vector<int> v(10);
12     vector<int>::iterator it;
13
14     sort(first, first+5);
15     sort(second, second+5);
16
17     it = set_union(first, first + 5, second, second + 5, v.begin());
18
19     cout << int(it - v.begin()) << endl;

我通读了 http://www.cplusplus.com/reference/algorithm/set_union/的set_union文件. 我有两个问题:

  • 第 17 行。 我知道set_union()正在返回一个输出迭代器。 我思想迭代器就像从容器对象返回的对象(例如,实例化的向量类,并调用blah.begin()返回迭代器对象)。 我试图了解什么"它"从set_union点返回,哪个对象?
  • 第 19 行。 "it - v.begin()"等于什么。 我从"8"的输出值猜测,联合的大小,但是如何?

如果有人能提供一些启示,将不胜感激。

谢谢艾哈迈德。

set_union的文档指出,返回的迭代器指向构造范围的末尾,在您的情况下指向 set_union 写入的 v 中最后一个元素。

这也是it - v.begin()导致集合并集长度的原因。请注意,您只能简单地减去两者,因为vector<T>::iterator必须满足 RandomAccessIterator 概念。理想情况下,您应该使用 std::distance 来确定两个迭代器之间的间隔。

您的代码片段可以更习惯地编写,如下所示:

int first[] = {5, 10, 15, 20, 25};
int second[] = {50, 40, 30, 20, 10};
std::vector<int> v;
v.reserve(10);  // reserve instead of setting an initial size
sort(std::begin(first), std::end(first));       
sort(std::begin(second), std::begin(second));
// use std::begin/end instead of hard coding length
auto it = set_union(std::begin(first), std::end(first), 
                    std::begin(second), std::end(second), 
                    std::back_inserter(v));
// using back_inserter ensures the code works even if the vector is not 
// initially set to the right size
std::cout << std::distance(v.begin(), it) << std::endl;
std::cout << v.size() << std::endl;
// these lines will output the same result unlike your example

回应您在下面的评论

创建大小为 10

的向量或保留大小 10 有什么用

在原始示例中,必须创建一个初始大小至少为 8 的vector以防止未定义的行为,因为set_union会将 8 个元素写入输出范围。保留 10 个元素的目的是优化以防止多次重新分配vector的可能性。这通常是不需要的,或者是不可行的,因为您不会提前知道结果的大小。

我尝试使用尺寸 1,工作正常

大小 1 绝对不能很好地处理您的代码,这是未定义的行为。 set_union将写过vector的结尾.出于同样的原因,您会遇到大小为 0 的 seg 错误。推测为什么在第一种情况下没有发生同样的事情是没有意义的,这只是未定义行为的本质。

set_union是否修剪矢量的大小,从 10 到 8。为什么或就是这样 set_union() 的工作原理

你只是将迭代器传递给set_union,它对底层容器一无所知。因此,它不可能修剪多余的元素,或者在需要时为更多元素腾出空间。它只是继续写入输出迭代器,并在每次写入后递增迭代器。这就是为什么我建议使用 back_inserter ,这是一个迭代器适配器,每当迭代器写入时都会调用vector::push_back()。这保证了set_union永远不会超出vector的范围。

first:"it"是构造范围末尾的迭代器(即相当于v.end())

第二:它 - v.begin() 等于 8,因为向量迭代器通常只是类型定义的指针,因此它只是在做指针算术。一般来说,使用距离算法比依赖原始减法更好

cout << distance(v.begin(), it) << endl;