C++ 从2个向量中提取元素?

C++ 从2个向量中提取元素?,c++,vector,iterator,containers,C++,Vector,Iterator,Containers,我有两个向量,一个是向量1{e1,e2,e3,e4},另一个是向量2{e2,e4,e5,e7} 如何有效地从上述向量中获取三个向量,以便1.具有仅在vec1中可用的元素2.类似地,2.仅具有vec2元素,3.具有公共元素std::set_intersection,如果两个向量都已排序,则应执行以下操作: 自定义谓词也可用于比较: std::set_intersection(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), std::back

我有两个向量,一个是向量1{e1,e2,e3,e4},另一个是向量2{e2,e4,e5,e7}


如何有效地从上述向量中获取三个向量,以便1.具有仅在vec1中可用的元素2.类似地,2.仅具有vec2元素,3.具有公共元素

std::set_intersection
,如果两个向量都已排序,则应执行以下操作:

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

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

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

如果元素计数较低,您可以使用易于实现且运行时间为O(n2)的朴素方法


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

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

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


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

你想要的是
vec3
是另外两个的交叉点。Jalf演示如何使用中的
std::set_intersection
函数填充
vec3
。但请记住,要使set函数起作用,必须对向量进行排序

然后您希望
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;
std::向量温度;
设置差异(vec1.begin(),vec1.end(),
vec3.begin(),vec3.end(),
标准:背部插入器(温度);
vec1=温度;
温度清除();
设置差异(vec2.begin(),vec2.end(),
vec3.begin(),vec3.end(),
标准:背部插入器(温度);
vec2=温度;

元素的类型是什么?它们是否具有可比性?是否只有4个元素?是的,它们是可比较的,而不仅仅是4个元素
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;