对C++向量的交集

Posted

技术标签:

【中文标题】对C++向量的交集【英文标题】:Intersection of vector of pair c++ 【发布时间】:2016-03-27 00:14:36 【问题描述】:

我有以下向量:

 vector<unsigned> A,B1;
 vector<pair<unsigned,unsigned> > B2;

我想执行(A,B1) 的交集,然后是(A,B2) 的交集。然后我想执行两个交集结果的并集。向量AB1 包含已排序的无符号整数,向量B2 包含成对的(start,end) 值。示例向量AB2,它们的交集向量如下所示:

   vector<unsigned> A(2,4,6,8,9,10,34,74,79,81,89,91,95);
   vector<pair<unsigned,unsigned> > B2= 2, 3, 29, 40, 60, 85 ;
   vector<unsigned> intersection; //result of intersection of A and B2 -> Procedure of performing intersection is explained below
   //intersection=(2,34,74,79,81);

22 相交,2,3。类似地,3434 相交,位于 29,40 之间。同样,747981 处于交集状态,因为它们位于 B2 的最后一个元素 60,85 的范围内。

是否有一些有效的方法可以得到与以下相同的结果:

(1)。交叉口AB1; (2)。 AB2 的交集; (3)。在步骤 1 和 2 中执行的两个交叉点的并集(即交叉点 (A,B1)(A,B2)

【问题讨论】:

是的,有:编写您自己的高效代码来执行此操作。 C++ 库中没有实现这种高度特定算法的现有函数,因此您可以自己编写代码。祝你好运。 【参考方案1】:

更新:

重新阅读问题后,我意识到您可能想同时执行所有三个操作。

我们可以通过将三个函数合二为一并返回一个元组,将外循环的迭代次数减少到一次,并删除一个内循环:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <tuple>


std::tuple<std::vector<unsigned>, std::vector<unsigned>, std::vector<unsigned>>
find_everything(const std::vector<unsigned>& a,
                const std::vector<std::pair<unsigned,unsigned> >& b1,
                const std::vector<std::pair<unsigned,unsigned> >& b2)

    std::vector<unsigned> r1, r2, both;

    for (auto x : a)
    
        auto either = false;
        auto i = std::find_if(std::begin(b1),
                              std::end(b1),
                              [x](const auto& range)
                               return x >= range.first && x < range.second; );
        if (i != std::end(b1)) 
            either = true;
            r1.push_back(x);
        

        i = std::find_if(std::begin(b2),
                              std::end(b2),
                              [x](const auto& range)
                               return x >= range.first && x < range.second; );
        if (i != std::end(b2)) 
            either = true;
            r2.push_back(x);
        

        if (either) 
            both.push_back(x);
        
    
    return std::make_tuple(std::move(r1), std::move(r2), std::move(both));




int main()


    using namespace std;

    vector<unsigned> A  2,4,6,8,9,10,34,74,79,81,89,91,95 ;
    vector<pair<unsigned,unsigned> > B1= 4, 5, 8, 10, 90, 99 ;
    vector<pair<unsigned,unsigned> > B2= 2, 3, 29, 40, 60, 85 ;

    auto results = find_everything(A, B1, B2);
    const auto& r1 = std::get<0>(results);
    const auto& r2 = std::get<1>(results);
    const auto& both = std::get<2>(results);
    copy(begin(r1), end(r1), ostream_iterator<unsigned>(cout, ", "));
    cout << endl;

    copy(begin(r2), end(r2), ostream_iterator<unsigned>(cout, ", "));
    cout << endl;

    copy(begin(both), end(both), ostream_iterator<unsigned>(cout, ", "));
    cout << endl;

    return 0;

预期结果:

4, 8, 9, 91, 95,
2, 34, 74, 79, 81,
2, 4, 8, 9, 34, 74, 79, 81, 91, 95,

进一步的工作:

如果数据集很大,我们可以立即做出两个明显的改进:

    由于 A、B1 和 B2 已排序,我们可以跟踪“当前”匹配迭代器,减少每次匹配或不匹配的搜索空间(这开始争论 std::lower_bound

    或者如果 A 明显大于 B1 和 B2,我们可以并行搜索。

玩得开心:)

【讨论】:

以上是关于对C++向量的交集的主要内容,如果未能解决你的问题,请参考以下文章

向量中的字符串交集给出分段错误

C++ 两个数组的交集

查找两个字符串向量的交集

在字符向量列表中查找任何交集

C++判断元素是否在vector中,对vector去重,两个vector求交集并集

查找分组变量的并集和交集