我使用算法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的文档。我有两个问题:
如果有人可以解释一下,我会非常感激。
谢谢你, 艾哈迈德。
答案 0 :(得分:1)
set_union
的文档声明返回的迭代器指向超出构造范围的末尾,在您的情况下是v
中由set_union
写入的最后一个元素的一个。it - v.begin()
。
这就是vector<T>::iterator
导致集合联盟长度的原因。请注意,您只能简单地减去两者,因为std::distance
必须满足RandomAccessIterator概念。理想情况下,您应该使用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
来计算两个迭代器之间的间隔。
您的代码段可以更加惯用地编写,如下所示:
vector
回复您的评论
创建大小为10或保留大小为10的向量有什么用?
在原始示例中,创建初始大小至少为8的set_union
是必要的,以防止未定义的行为,因为vector
将8个元素写入输出范围。保留10个元素的目的是优化以防止set_union
的多次重新分配的可能性。这通常不需要或不可行,因为您不会事先知道结果的大小。
我试过尺码1,工作正常
大小为1肯定不能正常使用您的代码,它是未定义的行为。 vector
将在set_union
的末尾写出来。出于同样的原因,您会得到大小为0的seg错误。没有必要推测为什么在第一种情况下不会发生同样的事情,这只是未定义行为的本质。
set_union是否修剪了向量的大小,从10到8.为什么或者是set_union()的工作原理
您只是将迭代器传递给vector::push_back()
,它知道没有关于底层容器。因此,如果需要,它无法修剪多余的元素,或者为更多元素腾出空间。它只是继续写入输出迭代器并在每次写入后递增迭代器。这就是为什么我建议使用back_inserter
,这是一个迭代器适配器,只要写入迭代器就会调用set_union
。这可以保证vector
永远不会超出{{1}}的范围。
答案 1 :(得分:0)
首先:&#34;它&#34;是构造范围末尾的迭代器(即等效于v.end())
第二:它 - v.begin()等于8,因为向量迭代器通常只是typedefed指针,因此它只是做指针运算。通常,使用距离算法比依赖原始减法更好
cout << distance(v.begin(), it) << endl;