我有2个向量,其中一个有vec1 {e1,e2,e3,e4},另一个有vec2 {e2,e4,e5,e7}
如何从上面的向量中有效地得到三个向量,使得1.has只有在vec1中可用的元素类似2只有vec2元素和3.with共同元素
答案 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
。但请记住,要使设置函数起作用,必须对矢量进行排序。
然后,您希望vec1
和vec2
成为他们与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)
您描述的问题是矢量交叉。这取决于输入向量的大小。
如果两个向量的大小彼此接近,则合并(如合并排序)最佳。如果一个向量比另一个向量小得多,则执行以下操作:对于较小向量的每个元素,使用二进制搜索在较大向量中搜索该元素。
这是信息检索中的常见问题,您必须将反向索引相交。有一些关于此的研究论文。