就地联合排序向量
我想要一种有效的方法来将排序向量与另一个排序向量进行就地并集。通过就地,我的意思是该算法不应该创建一个全新的向量或其他存储来存储并集,即使是暂时的。相反,第一个向量应该简单地按新元素的数量增长。
类似于:
void inplace_union(vector & A, const vector & B);
之后,A包含A联合B的所有元素并且被排序。
中的 std::set_union
不起作用,因为它覆盖了其目的地,即 A。
另外,这可以通过一次传递两个向量来完成吗?
编辑:同时 A 和 B 中的元素只能在 A 中出现一次。
I'd like an efficient method for doing the inplace union of a sorted vector with another sorted vector. By inplace, I mean that the algorithm shouldn't create a whole new vector or other storage to store the union, even temporarily. Instead, the first vector should simple grow by exactly the number of new elements.
Something like:
void inplace_union(vector & A, const vector & B);
Where, afterwards, A contains all of the elements of A union B and is sorted.
std::set_union
in <algorithm>
wont work because it overwrites its destination, which would be A.
Also, can this be done with just one pass over the two vectors?
Edit: elements that are in both A and B should only appear once in A.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我相信你可以使用算法
std::inplace_merge
。这是示例代码:I believe you can use the algorithm
std::inplace_merge
. Here is the sample code:是的,这可以在 O(n) 时间内就地完成,假设两个输入都已排序,并且一次传递两个向量。方法如下:
通过
B.size()
扩展A
(目标向量) - 为我们的新元素腾出空间。从
B
的末尾和A
的原始末尾开始向后迭代两个向量。如果向量按小→大排序(最后大),则将指向较大数字的迭代器放在A
的真实末尾。继续下去,直到B
的迭代器到达B
的开头。反向迭代器在这里应该特别好。示例:
超级编辑:您考虑过
std::inplace_merge
吗? (我可能刚刚重新发明了它?)Yes, this can be done in-place, and in O(n) time, assuming both inputs are sorted, and with one pass over both vectors. Here's how:
Extend
A
(the destination vector) byB.size()
- make room for our new elements.Iterate backwards over the two vectors, starting from the end of
B
and the original end ofA
. If the vectors are sorted small → big (big at the end), then take the iterator pointing at the larger number, and stick it in the true end ofA
. Keep going untilB
's iterator hits the beginning ofB
. Reverse iterators should prove especially nice here.Example:
Super edit: Have you considered
std::inplace_merge
? (which I may have just re-invented?)set_difference
的想法很好,但缺点是我们不知道需要提前将向量增长多少。这是我的解决方案,它执行两次
set_difference
,一次是为了计算我们需要的额外插槽的数量,另一次是为了执行实际的复制。注意:这意味着我们将迭代源两次。
使用 boost 头文件编译,结果是:
The
set_difference
idea is good, but the disadvantage is we don't know how much we need to grow the vector in advance.This is my solution which does the
set_difference
twice, once to count the number of extra slots we'll need, and once again to do the actual copy.Note: that means we will iterate over the source twice.
Compiled with the boost headers, the result is: