从2个向量中提取元素?

时间:2009-02-02 16:57:48

标签: c++ vector iterator containers

我有2个向量,其中一个有vec1 {e1,e2,e3,e4},另一个有vec2 {e2,e4,e5,e7}

如何从上面的向量中有效地得到三个向量,使得1.has只有在vec1中可用的元素类似2只有vec2元素和3.with共同元素

4 个答案:

答案 0 :(得分:6)

如果两个向量都已排序,那么

std::set_intersection应该可以解决问题: http://msdn.microsoft.com/en-us/library/zfd331yx.aspx

std::set_intersection(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), std::back_inserter(vec3));

自定义谓词也可用于比较:

std::set_intersection(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), std::back_inserter(vec3), my_equal_functor());

如果它们没有排序,你当然可以先对它们进行排序,或者你也可以遍历vec1,对于每个元素,使用std :: find查看它是否存在于vec2中。

答案 1 :(得分:3)

您要求的是vec3是其他两个的交叉点。 Jalf演示了如何使用the <algorithm> header中的vec3函数填充std::set_intersection。但请记住,要使设置函数起作用,必须对矢量进行排序

然后,您希望vec1vec2成为他们与vec3之间的差异。在集合表示法中:

vec1 := vec1 \ vec3;
vec2 := vec2 \ vec3;

您可以使用std::set_difference函数,但不能使用它来就地修改向量。你必须计算另一个向量来保持差异:

std::vector<foo> temp;
std::set_difference(vec1.begin(), vec1.end(),
                    vec3.begin(), vec3.end(),
                    std::back_inserter(temp));
vec1 = temp;
temp.clear();
std::set_difference(vec2.begin(), vec2.end(),
                    vec3.begin(), vec3.end(),
                    std::back_inserter(temp));
vec2 = temp;

答案 2 :(得分:1)

如果元素数量很少,您可以使用易于实现且具有O(n 2 )运行时间的朴素方法。

如果你有大量的元素,你可以从其中一个构建一个哈希表,并在其中查找其他向量的元素。或者,您可以对其中一个进行排序并通过它进行二进制搜索。

答案 3 :(得分:0)

您描述的问题是矢量交叉。这取决于输入向量的大小。

如果两个向量的大小彼此接近,则合并(如合并排序)最佳。如果一个向量比另一个向量小得多,则执行以下操作:对于较小向量的每个元素,使用二进制搜索在较大向量中搜索该元素。

这是信息检索中的常见问题,您必须将反向索引相交。有一些关于此的研究论文。